Add a pile of new instructions used by Pascal; I'm going to need to think about
authorDavid Given <dg@cowlark.com>
Sat, 15 Oct 2016 11:07:59 +0000 (13:07 +0200)
committerDavid Given <dg@cowlark.com>
Sat, 15 Oct 2016 11:07:59 +0000 (13:07 +0200)
how locals and the local base are handled.

mach/proto/mcg/parse_em.c
mach/proto/mcg/table
mach/proto/mcg/treebuilder.c
util/mcgg/ir.dat

index 167910a..27e3a8d 100644 (file)
@@ -243,6 +243,10 @@ static void parse_pseu(void)
                     data_offset(dlabel_to_str(em.em_dlb), em.em_off, ro);
                     break;
 
+                case sof_ptyp:
+                    data_offset(strdup(em.em_dnam), em.em_off, ro);
+                    break;
+
                 case ilb_ptyp:
                 {
                     const char* label = ilabel_to_str(em.em_ilb);
@@ -279,6 +283,18 @@ static void parse_pseu(void)
                     data_bss(EM_bsssize, em.em_cst);
                     break;
                     
+                               case ico_ptyp:
+                               case uco_ptyp:
+                {
+                    arith val = atol(em.em_string);
+                    data_int(val, em.em_size, false);
+                    break;
+                }
+
+                case sof_ptyp:
+                    data_offset(strdup(em.em_dnam), em.em_off, false);
+                    break;
+
                 default:
                     unknown_type("bss");
             }
index 9a94931..6a24d9e 100644 (file)
@@ -126,6 +126,18 @@ PATTERNS
                emit "addi sp, sp, $delta"
                cost 4;
 
+    out:(int)reg = GETFP4
+        emit "mr %out, fp"
+        cost 4;
+
+    out:(int)reg = FPTOARGS4(GETFP4)
+        emit "addi %out, fp, 8"
+        cost 4;
+
+    out:(int)reg = FPTOARGS4(in:(int)reg)
+        emit "addi %out, %in, 8"
+        cost 4;
+
 
 
 /* Memory operations */
@@ -354,6 +366,20 @@ PATTERNS
 
 
 
+/* Booleans */
+
+    out:(int)reg = IFEQ4(in:(cr)cr)
+        emit "mfcr %out" /* get cr0 */
+        emit "rlwinmi %out, %out, 32-2, 2, 31" /* extract just EQ */
+        cost 8;
+
+    out:(int)reg = IFEQ4(in:(int)reg)
+        emit "cntlzw %out, %in" /* returns 0..32 */
+        emit "rlwinmi %out, %out, 32-5, 5, 31" /* if 32, return 1, otherwise 0 */
+        cost 8;
+
+
+
 /* Conversions */
 
     out:(int)reg = CIU44(in:(int)reg)
@@ -406,6 +432,10 @@ PATTERNS
         emit "neg %out, %left"
         cost 4;
 
+       out:(int)reg = OR4(left:(int)reg, right:(int)reg)
+               emit "or %out, %right, %left"
+               cost 4;
+
        out:(int)reg = EOR4(left:(int)reg, right:(int)reg)
                emit "xor %out, %right, %left"
                cost 4;
index c2083b8..7f0abd1 100644 (file)
@@ -204,6 +204,15 @@ static void insn_simple(int opcode)
             );
             break;
 
+        case op_teq: 
+            push(
+                new_ir1(
+                    IR_IFEQ, EM_wordsize,
+                    pop(EM_wordsize)
+                )
+            );
+            break;
+
         case op_cai:
         {
             struct ir* dest = pop(EM_pointersize);
@@ -242,6 +251,35 @@ static void insn_simple(int opcode)
             break;
         }
 
+        case op_lim:
+        {
+            push(
+                new_ir1(
+                    IR_LOAD, 2,
+                    new_labelir(".ignmask")
+                )
+            );
+            break;
+        }
+
+        case op_sim:
+        {
+            appendir(
+                new_ir2(
+                    IR_STORE, 2,
+                    new_labelir(".ignmask"),
+                    pop(EM_wordsize)
+                )
+            );
+            break;
+        }
+
+        case op_lni:
+        {
+            /* Increment line number --- ignore. */
+            break;
+        }
+
         default:
             fatal("treebuilder: unknown simple instruction '%s'",
                 em_mnem[opcode - sp_fmnem]);
@@ -561,6 +599,7 @@ static void insn_ivalue(int opcode, arith value)
             break;
 
         case op_cmu:
+        case op_cms:
             push(
                 tristate_compare(value, IR_COMPAREU)
             );
@@ -717,6 +756,92 @@ static void insn_ivalue(int opcode, arith value)
             break;
         }
 
+        case op_sar:
+        case op_lar:
+        case op_aar:
+        {
+            const char* helper;
+            if (value != EM_wordsize)
+                fatal("sar/lar/aar are only supported when using "
+                    "word-size descriptors");
+
+            switch (opcode)
+            {
+                case op_sar: helper = ".sar4"; break;
+                case op_lar: helper = ".lar4"; break;
+                case op_aar: helper = ".aar4"; break;
+            }
+
+            materialise_stack();
+            appendir(
+                new_ir1(
+                    IR_CALL, 0,
+                    new_labelir(helper)
+                )
+            );
+            push(
+                new_ir0(
+                    IR_GETRET, EM_wordsize
+                )
+            );
+            break;
+        }
+
+        case op_lxl:
+        {
+            struct ir* ir;
+
+            /* Walk the static chain. */
+
+            ir = new_ir0(
+                IR_GETFP, EM_pointersize
+            );
+
+            while (value--)
+            {
+                ir = new_ir1(
+                    IR_CHAINFP, EM_pointersize,
+                    ir
+                );
+            }
+
+            push(ir);
+            break;
+        }
+
+        case op_lxa:
+        {
+            struct ir* ir;
+
+            /* Walk the static chain. */
+
+            ir = new_ir0(
+                IR_GETFP, EM_pointersize
+            );
+
+            while (value--)
+            {
+                ir = new_ir1(
+                    IR_CHAINFP, EM_pointersize,
+                    ir
+                );
+            }
+
+            push(
+                new_ir1(
+                    IR_FPTOARGS, EM_pointersize,
+                    ir
+                )
+            );
+            break;
+        }
+
+        case op_lin:
+        {
+            /* Set line number --- ignore. */
+            break;
+        }
+
         default:
             fatal("treebuilder: unknown ivalue instruction '%s'",
                 em_mnem[opcode - sp_fmnem]);
@@ -783,6 +908,12 @@ static void insn_lvalue(int opcode, const char* label, arith offset)
                 )
             );
             break;
+
+        case op_fil:
+        {
+            /* Set filename --- ignore. */
+            break;
+        }
                     
         default:
             fatal("treebuilder: unknown lvalue instruction '%s'",
index 0667ee0..44e28e9 100644 (file)
@@ -86,4 +86,7 @@ V RET
 S STACKADJUST
 S GETRET
 S SETRET
+S GETFP
+S CHAINFP
+S FPTOARGS