[hackers] [scc] [cc2-qbe] Add conversion between types || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Sat, 23 Apr 2016 11:27:28 +0200 (CEST)

commit 8013c0388602bef2e589f867a9bff8fa196247c7
Author: Roberto E. Vargas Caballero <Roberto E. Vargas Caballero>
AuthorDate: Fri Apr 22 17:14:09 2016 +0200
Commit: Roberto E. Vargas Caballero <Roberto E. Vargas Caballero>
CommitDate: Fri Apr 22 17:14:09 2016 +0200

    [cc2-qbe] Add conversion between types
    
    After this patch, we can begin to use char and short,
    because they are correctly promoted. It also includes
    conversion between float-float, integer-float and float-integer.

diff --git a/cc2/arch/qbe/arch.h b/cc2/arch/qbe/arch.h
index 683308c..031ec6e 100644
--- a/cc2/arch/qbe/arch.h
+++ b/cc2/arch/qbe/arch.h
_AT_@ -104,4 +104,25 @@ enum asmop {
         ASBORD,
         ASBXORD,
         ASCPLD,
+
+ ASEXTBW,
+ ASUEXTBW,
+ ASEXTBL,
+ ASUEXTBL,
+ ASEXTHW,
+ ASUEXTHW,
+ ASEXTHL,
+ ASUEXTHL,
+ ASEXTWL,
+ ASUEXTWL,
+
+ ASSTOL,
+ ASSTOW,
+ ASDTOL,
+ ASDTOW,
+
+ ASSWTOD,
+ ASSWTOS,
+ ASSLTOD,
+ ASSLTOS
 };
diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c
index 905a888..300f8dd 100644
--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
_AT_@ -1,4 +1,5 @@
 
+#include <assert.h>
 #include <stdlib.h>
 
 #include "arch.h"
_AT_@ -135,6 +136,76 @@ load(Node *np)
         return new;
 }
 
+static Node *
+cast(Node *nd, Node *ns)
+{
+ Type *ts, *td;
+ Node *tmp;
+ int op, disint, sisint;
+ extern Type uint32type, int32type;
+
+ if ((ns->flags & (ISTMP|ISCONS)) == 0)
+ ns = nd->left = load(ns);
+ td = &nd->type;
+ ts = &ns->type;
+ disint = (td->flags & INTF) != 0;
+ sisint = (ts->flags & INTF) != 0;
+
+ if (disint && sisint) {
+ if (td->size <= ts->size)
+ return nd;
+ assert(td->size == 4 || td->size == 8);
+ switch (ts->size) {
+ case 1:
+ op = (td->size == 4) ? ASEXTBW : ASEXTBL;
+ break;
+ case 2:
+ op = (td->size == 4) ? ASEXTHW : ASEXTHL;
+ break;
+ case 4:
+ op = ASEXTWL;
+ break;
+ default:
+ abort();
+ }
+ op += (td->flags & SIGNF) == 0;
+ } else if (disint) {
+ /* conversion from float to int */
+ switch (ts->size) {
+ case 4:
+ op = (td->size == 8) ? ASSTOL : ASSTOW;
+ break;
+ case 8:
+ op = (td->size == 8) ? ASDTOL : ASDTOW;
+ break;
+ default:
+ abort();
+ }
+ /* TODO: Add signess */
+ } else {
+ /* conversion from int to float */
+ switch (ts->size) {
+ case 1:
+ case 2:
+ tmp = tmpnode(newnode());
+ tmp->type = (ts->flags&SIGNF) ? int32type : uint32type;
+ tmp->left = ns;
+ nd->left = ns = cast(tmp, ns);
+ case 4:
+ op = (td->size == 8) ? ASSWTOD : ASSWTOS;
+ break;
+ case 8:
+ op = (td->size == 8) ? ASSLTOD : ASSLTOS;
+ break;
+ default:
+ abort();
+ }
+ /* TODO: Add signess */
+ }
+ code(op, tmpnode(nd), ns, NULL);
+ return nd;
+}
+
 Node *
 cgen(Node *np)
 {
_AT_@ -206,11 +277,13 @@ cgen(Node *np)
         case OBLOOP:
         case OELOOP:
                 return NULL;
+ case OCAST:
+ assert(r == NULL);
+ return cast(np, l);
         case OPAR:
         case ONEG:
         case OADDR:
         case OPTR:
- case OCAST:
         case OINC:
         case ODEC:
                 abort();
diff --git a/cc2/arch/qbe/code.c b/cc2/arch/qbe/code.c
index 2ed8ffd..0092576 100644
--- a/cc2/arch/qbe/code.c
+++ b/cc2/arch/qbe/code.c
_AT_@ -9,19 +9,19 @@
 
 #define ADDR_LEN (IDENTSIZ+64)
 
-static void binary(void), load(void), store(void);
+static void binary(void), unary(void), store(void);
 
 static struct opdata {
         void (*fun)(void);
         char *txt;
         char letter;
 } optbl [] = {
- [ASLDB] = {.fun = load, .txt = "load", .letter = 'b'},
- [ASLDH] = {.fun = load, .txt = "load", .letter = 'h'},
- [ASLDW] = {.fun = load, .txt = "load", .letter = 'w'},
- [ASLDL] = {.fun = load, .txt = "load", .letter = 'l'},
- [ASLDS] = {.fun = load, .txt = "load", .letter = 's'},
- [ASLDD] = {.fun = load, .txt = "load", .letter = 'd'},
+ [ASLDB] = {.fun = unary, .txt = "load", .letter = 'b'},
+ [ASLDH] = {.fun = unary, .txt = "load", .letter = 'h'},
+ [ASLDW] = {.fun = unary, .txt = "load", .letter = 'w'},
+ [ASLDL] = {.fun = unary, .txt = "load", .letter = 'l'},
+ [ASLDS] = {.fun = unary, .txt = "load", .letter = 's'},
+ [ASLDD] = {.fun = unary, .txt = "load", .letter = 'd'},
 
         [ASSTB] = {.fun = store, .txt = "store", .letter = 'b'},
         [ASSTH] = {.fun = store, .txt = "store", .letter = 'h'},
_AT_@ -99,6 +99,25 @@ static struct opdata {
         [ASGED] = {.fun = binary, .txt = "cged", .letter = 'w'},
         [ASEQD] = {.fun = binary, .txt = "ceqd", .letter = 'w'},
         [ASNED] = {.fun = binary, .txt = "cned", .letter = 'w'},
+
+ [ASEXTBW] = {.fun = unary, .txt = "extsb", .letter = 'w'},
+ [ASUEXTBW]= {.fun = unary, .txt = "extub", .letter = 'w'},
+ [ASEXTBL] = {.fun = unary, .txt = "extsb", .letter = 'l'},
+ [ASUEXTBL]= {.fun = unary, .txt = "extub", .letter = 'l'},
+ [ASEXTHW] = {.fun = unary, .txt = "extsh", .letter = 'w'},
+ [ASUEXTHW]= {.fun = unary, .txt = "extuh", .letter = 'w'},
+ [ASEXTWL] = {.fun = unary, .txt = "extsh", .letter = 'l'},
+ [ASUEXTWL]= {.fun = unary, .txt = "extuh", .letter = 'l'},
+
+ [ASSTOL] = {.fun = unary, .txt = "stosi", .letter = 'l'},
+ [ASSTOW] = {.fun = unary, .txt = "stosi", .letter = 'w'},
+ [ASDTOL] = {.fun = unary, .txt = "dtosi", .letter = 'l'},
+ [ASDTOW] = {.fun = unary, .txt = "dtosi", .letter = 'w'},
+
+ [ASSWTOD] = {.fun = unary, .txt = "swtof", .letter = 'd'},
+ [ASSWTOS] = {.fun = unary, .txt = "swtof", .letter = 's'},
+ [ASSLTOD] = {.fun = unary, .txt = "sltof", .letter = 'd'},
+ [ASSLTOS] = {.fun = unary, .txt = "sltof", .letter = 's'},
 };
 
 /*
_AT_@ -354,7 +373,7 @@ store(void)
 }
 
 static void
-load(void)
+unary(void)
 {
         struct opdata *p = &optbl[pc->op];
         char to[ADDR_LEN], from[ADDR_LEN];
Received on Sat Apr 23 2016 - 11:27:28 CEST

This archive was generated by hypermail 2.3.0 : Sat Apr 23 2016 - 11:36:14 CEST