scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit fa9a898e3d16f7f133e563e0cdd36a24724359d9
parent a9faecb3d9b2541461d0cb68bc5db78d86000e8c
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 16 Aug 2016 09:10:13 +0200

[cc2-qbe] Add cast()

This code is directly taken and adapted from the old
cgen for qbe.

Diffstat:
Mcc2/arch/qbe/cgen.c | 78+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 77 insertions(+), 1 deletion(-)

diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c @@ -90,7 +90,7 @@ static char opasmd[] = { [OCPL] = ASCPLD }; -extern Type int32type; +extern Type int32type, uint32type; static Node * tmpnode(Node *np, Type *tp) @@ -136,6 +136,80 @@ load(Node *np, Node *new) return new; } +static Node *rhs(Node *np, Node *new); + +static Node * +cast(Type *td, Node *ns, Node *nd) +{ + Type *ts; + Node aux1, aux2; + int op, d_isint, s_isint; + + ts = &ns->type; + d_isint = (td->flags & INTF) != 0; + s_isint = (ts->flags & INTF) != 0; + + if (d_isint && s_isint) { + 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(); + } + /* + * unsigned version of operations are always +1 the + * signed version + */ + op += (td->flags & SIGNF) == 0; + } else if (d_isint) { + /* 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 if (s_isint) { + /* conversion from int to float */ + switch (ts->size) { + case 1: + case 2: + ts = (ts->flags&SIGNF) ? &int32type : &uint32type; + ns = cast(ts, ns, tmpnode(&aux2, ts)); + case 4: + op = (td->size == 8) ? ASSWTOD : ASSWTOS; + break; + case 8: + op = (td->size == 8) ? ASSLTOD : ASSLTOS; + break; + default: + abort(); + } + /* TODO: Add signess */ + } else { + /* conversion from float to float */ + op = (td->size == 4) ? ASEXTS : ASTRUNCD; + } + + code(op, tmpnode(nd, td), ns, NULL); + return nd; +} + static Node * assign(Node *to, Node *from) { @@ -323,6 +397,8 @@ rhs(Node *np, Node *ret) tmpnode(ret, tp); code(op, ret, &aux1, &aux2); return ret; + case OCAST: + return cast(tp, rhs(l, &aux1), ret); case OASSIG: lhs(l, &aux1); rhs(r, ret);