shithub: scc

Download patch

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);