Lots more opcodes.
authorDavid Given <dg@cowlark.com>
Mon, 17 Oct 2016 22:31:26 +0000 (00:31 +0200)
committerDavid Given <dg@cowlark.com>
Mon, 17 Oct 2016 22:31:26 +0000 (00:31 +0200)
mach/powerpc/mcg/platform.c
mach/powerpc/mcg/table
mach/proto/mcg/treebuilder.c

index ab08209..2e59833 100644 (file)
@@ -90,7 +90,7 @@ struct hop* platform_epilogue(void)
     hop_add_insel(hop, "lwz r0, %d(fp)", current_proc->spills_size + 4);
     hop_add_insel(hop, "addi sp, fp, %d", current_proc->fp_to_ab);
     hop_add_insel(hop, "mr fp, r0");
-    hop_add_insel(hop, "blr");
+    hop_add_insel(hop, "bclr 20, 0, 0");
 
        return hop;
 }
index 95ba2a9..93bdb19 100644 (file)
@@ -269,7 +269,7 @@ PATTERNS
 /* Locals */
 
        out:(int)reg = in:LOCAL4
-               emit "addi %out, fp, #$in"
+               emit "addi %out, fp, $in"
                cost 4;
 
        address = in:LOCAL4
@@ -295,17 +295,17 @@ PATTERNS
                cost 4;
 
        CJUMPEQ(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4))
-        emit "bc IFTRUE, EQ, $true"
+        emit "bc 12, 2, $true" /* IFTRUE EQ */
                emit "b $false"
                cost 8;
 
        CJUMPLE(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4))
-        emit "bc IFTRUE, LE, $true"
+        emit "bc 4, 1, $true" /* IFFALSE GT */
         emit "b $false"
                cost 8;
 
        CJUMPLT(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4))
-        emit "bc IFTRUE, LT, $true"
+        emit "bc 12, 0, $true" /* IFTRUE LT */
         emit "b $false"
                cost 8;
 
@@ -317,7 +317,7 @@ PATTERNS
     CALL(dest:(int)reg)
         with corrupted(volatile)
         emit "mtspr ctr, %dest"
-        emit "bcctrl ALWAYS, 0, 0"
+        emit "bcctrl 20, 0, 0"
         cost 8;
 
     JUMP(dest:LABEL4)
@@ -381,11 +381,13 @@ PATTERNS
 /* Conversions */
 
     out:(int)reg = CIU44(in:(int)reg)
-        emit "mr %out, %in ! ciu44"
+        with %out == %in
+        emit "! ciu44"
         cost 4;
 
     out:(int)reg = CUI44(in:(int)reg)
-        emit "mr %out, %in ! cui44"
+        with %out == %in
+        emit "! cui44"
         cost 4;
 
 
@@ -410,7 +412,7 @@ PATTERNS
                cost 4;
 
        out:(int)reg = SUB4(left:(int)reg, right:CONST4)
-               emit "addi %out, %left, -($right)"
+               emit "addi %out, %left, -[$right]"
                cost 4;
 
        out:(int)reg = MUL4(left:(int)reg, right:(int)reg)
@@ -439,6 +441,18 @@ PATTERNS
         emit "neg %out, %left"
         cost 4;
 
+       out:(int)reg = AND4(left:CONST4, right:(int)reg)
+               emit "andi. %out, %right, $left"
+               cost 4;
+
+       out:(int)reg = AND4(left:(int)reg, right:CONST4)
+               emit "andi. %out, %left, $right"
+               cost 4;
+
+       out:(int)reg = AND4(left:(int)reg, right:(int)reg)
+               emit "and %out, %left, %right"
+               cost 4;
+
        out:(int)reg = OR4(left:(int)reg, right:(int)reg)
                emit "or %out, %right, %left"
                cost 4;
index e3d0f52..9fbae16 100644 (file)
@@ -528,6 +528,47 @@ static void insn_ivalue(int opcode, arith value)
             );
             break;
 
+        case op_loe:
+            push(
+                new_ir1(
+                    IR_LOAD, EM_wordsize,
+                    new_ir2(
+                        IR_ADD, EM_pointersize,
+                        new_labelir(".hol0"),
+                        new_wordir(value)
+                    )
+                )
+            );
+            break;
+
+        case op_ste:
+            appendir(
+                new_ir2(
+                    IR_STORE, EM_wordsize,
+                    new_ir2(
+                        IR_ADD, EM_pointersize,
+                        new_labelir(".hol0"),
+                        new_wordir(value)
+                    ),
+                    pop(EM_wordsize)
+                )
+            );
+            break;
+
+        case op_zre:
+            appendir(
+                new_ir2(
+                    IR_STORE, EM_wordsize,
+                    new_ir2(
+                        IR_ADD, EM_pointersize,
+                        new_labelir(".hol0"),
+                        new_wordir(value)
+                    ),
+                    new_wordir(0)
+                )
+            );
+            break;
+                
         case op_loc:
             push(
                 new_wordir(value)
@@ -577,7 +618,7 @@ static void insn_ivalue(int opcode, arith value)
         case op_stf:
         {
             struct ir* ptr = pop(EM_pointersize);
-            struct ir* val = pop(value);
+            struct ir* val = pop(EM_wordsize);
 
             appendir(
                 new_ir2(
@@ -854,6 +895,48 @@ static void insn_ivalue(int opcode, arith value)
             break;
         }
 
+        case op_fef:
+        {
+            struct ir* e;
+            struct ir* f = pop(value);
+            /* fef is implemented by synthesising a call to frexp. */
+            push(
+                new_labelir(".fef_exp")
+            );
+            push(
+                f
+            );
+            materialise_stack();
+            appendir(
+                new_ir1(
+                    IR_CALL, 0,
+                    new_labelir((value == 4) ? "frexpf" : "frexp")
+                )
+            );
+            appendir(
+                new_ir1(
+                    IR_STACKADJUST, EM_wordsize,
+                    new_wordir(4 + value)
+                )
+            );
+            e = appendir(
+                new_ir0(
+                    IR_GETRET, value
+                )
+            );
+            push(
+                new_ir1(
+                    IR_LOAD, EM_wordsize,
+                    new_labelir(".fef_exp")
+                )
+            );
+            push(
+                e
+            );
+                    
+            break;
+        }
+            
         case op_lin:
         {
             /* Set line number --- ignore. */
@@ -905,6 +988,40 @@ static void insn_lvalue(int opcode, const char* label, arith offset)
             );
             break;
                 
+        case op_ine:
+            appendir(
+                new_ir2(
+                    IR_STORE, EM_wordsize,
+                    address_of_external(label, offset),
+                    new_ir2(
+                        IR_ADD, EM_wordsize,
+                        new_ir1(
+                            IR_LOAD, EM_wordsize,
+                            address_of_external(label, offset)
+                        ),
+                        new_wordir(1)
+                    )
+                )
+            );
+            break;
+
+        case op_dee:
+            appendir(
+                new_ir2(
+                    IR_STORE, EM_wordsize,
+                    address_of_external(label, offset),
+                    new_ir2(
+                        IR_ADD, EM_wordsize,
+                        new_ir1(
+                            IR_LOAD, EM_wordsize,
+                            address_of_external(label, offset)
+                        ),
+                        new_wordir(-1)
+                    )
+                )
+            );
+            break;
+
         case op_cal:
             assert(offset == 0);
             materialise_stack();