ref: 38da5860529e4b248b4c80d6c539e1eab5bb3bc4
parent: dd645ca9e70c446ad5e785a882ff43ac0c1868d0
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Aug 16 05:10:13 EDT 2016
[cc2-qbe] Add cast() This code is directly taken and adapted from the old cgen for qbe.
--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
@@ -90,7 +90,7 @@
[OCPL] = ASCPLD
};
-extern Type int32type;
+extern Type int32type, uint32type;
static Node *
tmpnode(Node *np, Type *tp)
@@ -136,7 +136,81 @@
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)
{
Type *tp;
@@ -323,6 +397,8 @@
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);