Instruction predicates work now.
authorDavid Given <dg@cowlark.com>
Sat, 8 Oct 2016 09:35:33 +0000 (11:35 +0200)
committerDavid Given <dg@cowlark.com>
Sat, 8 Oct 2016 09:35:33 +0000 (11:35 +0200)
mach/proto/mcg/mcgg_generated_header.h
mach/proto/mcg/powerpc_predicates.c [new file with mode: 0644]
mach/proto/mcg/table
util/mcgg/iburg.c

index 8ca4c4b..47c2bd9 100644 (file)
@@ -8,5 +8,8 @@
 
 extern void burm_panic_cannot_match(NODEPTR_TYPE node);
 
+extern bool burm_predicate_constant_signed_16_bit(struct burm_node* node);
+extern bool burm_predicate_constant_is_zero(struct burm_node* node);
+
 /* vim: set sw=4 ts=4 expandtab : */
 
diff --git a/mach/proto/mcg/powerpc_predicates.c b/mach/proto/mcg/powerpc_predicates.c
new file mode 100644 (file)
index 0000000..2748b43
--- /dev/null
@@ -0,0 +1,19 @@
+#include "mcg.h"
+
+bool burm_predicate_constant_signed_16_bit(struct burm_node* node)
+{
+       struct ir* ir = node->ir;
+       assert(ir->opcode == IR_CONST);
+       return (ir->u.ivalue >= -0x8000) && (ir->u.ivalue <= 0x7fff);
+}
+
+bool burm_predicate_constant_is_zero(struct burm_node* node)
+{
+       struct ir* ir = node->ir;
+       assert(ir->opcode == IR_CONST);
+       return (ir->u.ivalue == 0);
+}
+
+/* vim: set sw=4 ts=4 expandtab : */
+
+
index f3f359f..c589101 100644 (file)
@@ -1,38 +1,78 @@
 REGISTERS
 
-       r0  bytes4 int ret;
-       r1  bytes4 int;
-       r2  bytes4 int;
-       r3  bytes4 int;
-       r4  bytes4 int;
-       r5  bytes4 int;
-       r6  bytes4 int;
-       r7  bytes4 int;
-       r8  bytes4 int;
-       r9  bytes4 int;
-       r10 bytes4 int;
-       r11 bytes4 int;
-
-       s0  bytes4 float;
-       s1  bytes4 float;
-       s2  bytes4 float;
-       s3  bytes4 float;
-       s4  bytes4 float;
-       s5  bytes4 float;
-       s6  bytes4 float;
-       s7  bytes4 float;
-       s8  bytes4 float;
-       s9  bytes4 float;
-
-       cc  cc;
+    /* Reverse order because registers are assigned from top down. */
+
+    r31 bytes4 int; 
+    r30 bytes4 int; 
+    r29 bytes4 int; 
+    r28 bytes4 int; 
+    r27 bytes4 int; 
+    r26 bytes4 int; 
+    r25 bytes4 int; 
+    r24 bytes4 int; 
+    r23 bytes4 int; 
+    r22 bytes4 int; 
+    r21 bytes4 int; 
+    r20 bytes4 int; 
+    r19 bytes4 int; 
+    r18 bytes4 int; 
+    r17 bytes4 int; 
+    r16 bytes4 int; 
+    r15 bytes4 int; 
+    r14 bytes4 int; 
+    r13 bytes4 int; 
+    r12 bytes4 int; 
+    r11 bytes4 int; 
+    r10 bytes4 int; 
+    r9  bytes4 int;
+    r8  bytes4 int;
+    r7  bytes4 int;
+    r6  bytes4 int;
+    r5  bytes4 int;
+    r4  bytes4 int;
+    r3  bytes4 int ret;
+
+    f31 bytes4 bytes8 float;
+    f30 bytes4 bytes8 float;
+    f29 bytes4 bytes8 float;
+    f28 bytes4 bytes8 float;
+    f27 bytes4 bytes8 float;
+    f26 bytes4 bytes8 float;
+    f25 bytes4 bytes8 float;
+    f24 bytes4 bytes8 float;
+    f23 bytes4 bytes8 float;
+    f22 bytes4 bytes8 float;
+    f21 bytes4 bytes8 float;
+    f20 bytes4 bytes8 float;
+    f19 bytes4 bytes8 float;
+    f18 bytes4 bytes8 float;
+    f17 bytes4 bytes8 float;
+    f16 bytes4 bytes8 float;
+    f15 bytes4 bytes8 float;
+    f14 bytes4 bytes8 float;
+    f13 bytes4 bytes8 float;
+    f12 bytes4 bytes8 float;
+    f11 bytes4 bytes8 float;
+    f10 bytes4 bytes8 float;
+    f9  bytes4 bytes8 float;
+    f8  bytes4 bytes8 float;
+    f7  bytes4 bytes8 float;
+    f6  bytes4 bytes8 float;
+    f5  bytes4 bytes8 float;
+    f4  bytes4 bytes8 float;
+    f3  bytes4 bytes8 float;
+    f2  bytes4 bytes8 float;
+    f1  bytes4 bytes8 float;
+    f0  bytes4 bytes8 float;
+
+       cr0  cr;
 
 
 DECLARATIONS
 
-       cc;
+       cr;
 
        address   fragment;
-       aluparam  fragment;
 
 
 PATTERNS
@@ -42,16 +82,23 @@ PATTERNS
        PAIR(BLOCK4, BLOCK4);
 
 
+
 /* Miscellaneous special things */
 
        PUSH4(in:(int)reg)
-               emit "push %in"
+               emit "stwu %in, -4(sp)"
                cost 4;
 
        out:(int)reg = POP4
-               emit "pop %out"
-               cost 4;
+               emit "lwz %out, 0(sp)"
+        emit "addi sp, sp, 4"
+               cost 8;
 
+       out:(float)reg = POPF4
+               emit "lfs %out, 0(sp)"
+               emit "addi sp, sp, 4"
+               cost 8;
+               
        RET
                emit "ret"
                cost 4;
@@ -60,58 +107,71 @@ PATTERNS
                emit "mov r0, %in"
                cost 4;
 
-       STACKADJUST4(delta:aluparam)
-               emit "add sp, sp, %delta"
+    (ret)reg = GETRET4
+        cost 1;
+
+       STACKADJUST4(delta:CONST4)
+        when constant_signed_16_bit(delta)
+               emit "addi sp, sp, $delta"
                cost 4;
 
 
+
 /* Memory operations */
 
        STORE4(addr:address, value:(int)reg)
-               emit "str %value, %addr"
+               emit "stw %value, %addr"
+               cost 4;
+
+       STORE2(addr:address, value:(int)reg)
+               emit "sth %value, %addr"
                cost 4;
 
        STORE1(addr:address, value:(int)reg)
-               emit "strb %value, %addr"
+               emit "stb %value, %addr"
                cost 4;
 
        out:(int)reg = LOAD4(addr:address)
-               emit "ldr %out, %addr"
+               emit "lwz %out, %addr"
+               cost 4;
+
+       out:(int)reg = LOAD2(addr:address)
+               emit "lhz %out, %addr"
                cost 4;
 
        out:(int)reg = LOAD1(addr:address)
-               emit "ldrb %out, %addr"
+               emit "lbz %out, %addr"
                cost 4;
 
        out:(int)reg = CIU14(LOAD1(addr:address))
-               emit "ldrb %out, %addr"
+               emit "lbz %out, %addr"
                cost 4;
-       
-       out:(int)reg = CII14(CIU41(CIU14(LOAD1(addr:address))))
-               emit "ldrsb %out, %addr"
+
+       out:(int)reg = CIU24(LOAD2(addr:address))
+               emit "lhz %out, %addr"
                cost 4;
+       
 
 
 /* Locals */
 
        out:(int)reg = in:LOCAL4
-               emit "add %out, fp, #$in"
+               emit "addi %out, fp, #$in"
                cost 4;
 
        address = in:LOCAL4
-               emit "[fp, #$in]";
+               emit "$in(fp)";
+
 
 
 /* Memory addressing modes */
 
        address = ADD4(addr:(int)reg, offset:CONST4)
-               emit "[%addr, #$offset]";
-
-       address = ADD4(addr1:(int)reg, addr2:(int)reg)
-               emit "[%addr1, %addr2]";
+        when constant_signed_16_bit(offset)
+               emit "$offset(%addr)";
 
        address = addr:(int)reg
-               emit "[%addr]";
+               emit "0(%addr)";
 
 
 
@@ -121,99 +181,153 @@ PATTERNS
                emit "b $addr"
                cost 4;
 
-       CJUMPEQ(value:(cc)cc, PAIR(true:BLOCK4, false:BLOCK4))
-               emit "beq $true"
+       CJUMPEQ(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4))
+        emit "bc IFTRUE, EQ, $true"
                emit "b $false"
                cost 8;
 
-       CJUMPLE(value:(cc)cc, PAIR(true:BLOCK4, false:BLOCK4))
-               emit "ble $true"
-               emit "b $false"
+       CJUMPLE(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4))
+        emit "bc IFTRUE, LE, $true"
+        emit "b $false"
                cost 8;
 
-       CJUMPLT(value:(cc)cc, PAIR(true:BLOCK4, false:BLOCK4))
-               emit "blt $true"
-               emit "b $false"
+       CJUMPLT(value:(cr)cr, PAIR(true:BLOCK4, false:BLOCK4))
+        emit "bc IFTRUE, LT, $true"
+        emit "b $false"
                cost 8;
 
        CALL(dest:LABEL4)
                emit "bl $dest"
                cost 4;
 
+    CALL(dest:(int)reg)
+        emit "mtspr ctr, %dest"
+        emit "bcctrl ALWAYS, 0, 0"
+        cost 8;
+
+    JUMP(dest:LABEL4)
+        emit "b $dest"
+        cost 4;
+
+
 
 /* Comparisons */
 
-       (cc)cc = COMPARES4(left:(int)reg, right:aluparam)
-               emit "cmp %left, %right"
+       cr:(cr)cr = COMPARES4(left:(int)reg, right:(int)reg)
+        emit "cmp %cr, 0, %left, %right"
                cost 4;
 
-       (cc)cc = COMPARES4(COMPARES4(left:(int)reg, right:aluparam), CONST4)
-               emit "cmp %left, %right"
+       cr:(cr)cr = COMPARES4(left:(int)reg, right:CONST4)
+        when constant_signed_16_bit(right)
+        emit "cmpi %cr, 0, %left, $right"
                cost 4;
 
-       out:(int)reg = (cc)cc
-               emit "mov %out, #0"
-               emit "movlt %out, #-1"
-               emit "movgt %out, #1"
-               cost 12;
+       cr:(cr)cr = COMPAREU4(left:(int)reg, right:(int)reg)
+        emit "cmpl %cr, 0, %left, %right"
+               cost 4;
+
+       cr:(cr)cr = COMPAREU4(left:(int)reg, right:CONST4)
+        when constant_signed_16_bit(right)
+        emit "cmpli %cr, 0, %left, $right"
+               cost 4;
+
+    cr:(cr)cr = COMPARES4(COMPARES4(left:(int)reg, right:(int)reg), result:CONST4)
+        when constant_is_zero(result)
+        emit "cmp %cr, 0, %left, %right"
+        cost 4;
+
+    cr:(cr)cr = COMPARES4(COMPARES4(left:(int)reg, right:CONST4), result:CONST4)
+        when constant_is_zero(result)
+        when constant_signed_16_bit(right)
+        emit "cmpi %cr, 0, %left, $right"
+        cost 4;
+
+    cr:(cr)cr = COMPARES4(COMPAREU4(left:(int)reg, right:(int)reg), result:CONST4)
+        when constant_is_zero(result)
+        emit "cmpl %cr, 0, %left, %right"
+        cost 4;
+
 
 
 /* Conversions */
 
        out:(int)reg = CII14(CIU41(value:(int)reg))
-               emit "sxtb %out, %value"
+               emit "extsb %out, %value"
+               cost 4;
+
+       out:(int)reg = CII24(CIU42(value:(int)reg))
+               emit "extsh %out, %value"
                cost 4;
 
        out:(int)reg = CIU41(in:(int)reg)
-               emit "and %out, %in, #0xff"
+               emit "andi %out, %in, 0xff"
                cost 4;
 
+       out:(int)reg = CIU42(in:(int)reg)
+               emit "andi %out, %in, 0xffff"
+               cost 4;
+
+    out:(int)reg = CIU44(in:(int)reg)
+        emit "mr %out, %in"
+        cost 4;
+
+
 
 /* ALU operations */
 
-       out:(int)reg = ADD4(left:(int)reg, right:aluparam)
+       out:(int)reg = ADD4(left:(int)reg, right:(int)reg)
                emit "add %out, %left, %right"
                cost 4;
 
-       out:(int)reg = ADD4(left:aluparam, right:(int)reg)
-               emit "add %out, %right, %left"
+       out:(int)reg = ADD4(left:(int)reg, right:CONST4)
+        when constant_signed_16_bit(right)
+               emit "addi %out, %left, $right"
                cost 4;
 
-       out:(int)reg = MOD4(left:(int)reg, right:(int)reg)
-               emit "udiv %out, %left, %right"
-               emit "mls %out, %out, %right, %left"
-               cost 8;
+       out:(int)reg = SUB4(left:(int)reg, right:(int)reg)
+               emit "sub %out, %right, %left"
+               cost 4;
 
-       out:(int)reg = DIV4(left:(int)reg, right:aluparam)
-               emit "div %out, %left, %right"
+       out:(int)reg = MUL4(left:(int)reg, right:(int)reg)
+               emit "mullw %out, %right, %left"
                cost 4;
 
-       aluparam = value:CONST4
-               emit "#$value";
+       out:(int)reg = MOD4(left:(int)reg, right:(int)reg)
+               emit "divw %out, %left, %right"
+        emit "mullw %out, %out, %right"
+        emit "subf %out, %out, %left"
+               cost 12;
+
+       out:(int)reg = DIV4(left:(int)reg, right:(int)reg)
+               emit "divw %out, %left, %right"
+               cost 4;
 
-       aluparam = value:(int)reg
-               emit "%value";
+    out:(int)reg = NEG4(left:(int)reg)
+        emit "neg %out, %left"
+        cost 4;
 
-       out:(int)reg = value:aluparam
-               emit "mov %out, %value"
+       out:(int)reg = EOR4(left:(int)reg, right:(int)reg)
+               emit "xor %out, %right, %left"
                cost 4;
 
        out:(int)reg = value:LABEL4
-               emit "adr %out, $value"
+               emit "la %out, $value"
                cost 4;
 
        out:(int)reg = value:BLOCK4
-               emit "adr %out, $value"
+               emit "la %out, $value"
                cost 4;
 
        out:(int)reg = value:CONST4
-               emit "ldr %out, address-containing-$value"
+               emit "la %out, $value"
                cost 8;
 
        out:(int)reg = value:CONSTF4
-               emit "vldr %out, address-containing-$value"
+               emit "lfs %out, address-containing-$value"
                cost 8;
 
+
+
 /* FPU operations */
 
        out:(float)reg = ADDF4(left:(float)reg, right:(float)reg)
index 5683b6c..5500111 100644 (file)
@@ -1000,6 +1000,31 @@ static bool find_child_index(Tree node, const char* name, int* index, Tree* foun
        return false;
 }
        
+static void emit_predicate_expr(Rule r, struct expr* p)
+{
+       bool first = true;
+
+       print("%1if (%Ppredicate_%s(", p->name);
+
+       p = p->next;
+       while (p)
+       {
+               uint32_t path = find_label(r->pattern, p->name, 0, NULL);
+               if (path == PATH_MISSING)
+                       label_not_found(r, p->name);
+
+               if (!first)
+                       print(", ");
+               else
+                       first = false;
+
+               print_path(path);
+               p = p->next;
+       }
+
+       print("))");
+}
+
 /* emitpredicates - emit predicates for rules */
 static void emitpredicatedefinitions(Rule r)
 {
@@ -1012,28 +1037,14 @@ static void emitpredicatedefinitions(Rule r)
 
                for (i=0; i<r->prefers.count; i++)
                {
-                       struct expr* p = r->prefers.item[i];
-                       bool first = true;
-
-                       print("%1if (%Ppredicate_%s(", p->name);
-
-                       p = p->next;
-                       while (p)
-                       {
-                               uint32_t path = find_label(r->pattern, p->name, 0, NULL);
-                               if (path == PATH_MISSING)
-                                       label_not_found(r, p->name);
-
-                               if (!first)
-                                       print(", ");
-                               else
-                                       first = false;
-
-                               print_path(path);
-                               p = p->next;
-                       }
+                       emit_predicate_expr(r, r->prefers.item[i]);
+                       print(" cost -= 1;\n");
+               }
 
-                       print(")) cost -= 1;\n");
+               for (i=0; i<r->requires.count; i++)
+               {
+                       emit_predicate_expr(r, r->requires.item[i]);
+                       print(" {} else return %d;\n", maxcost);
                }
 
                print("%1if (cost > %d) return %d;\n", maxcost, maxcost);