More opcodes, including the difficult and fairly stupid los/sts.
authorDavid Given <dg@cowlark.com>
Sun, 23 Oct 2016 20:24:08 +0000 (22:24 +0200)
committerDavid Given <dg@cowlark.com>
Sun, 23 Oct 2016 20:24:08 +0000 (22:24 +0200)
mach/powerpc/mcg/table
mach/proto/mcg/parse_em.c
mach/proto/mcg/treebuilder.c

index 2c3565a..448e112 100644 (file)
@@ -194,6 +194,10 @@ PATTERNS
                emit "add sp, sp, %in"
                cost 4;
 
+       STACKADJUST.I(NEG.I(in:(int)reg))
+               emit "subf sp, %in, sp"
+               cost 4;
+
     out:(int)reg = GETFP.I
         emit "mr %out, fp"
         cost 4;
index 9551ecd..26754b1 100644 (file)
@@ -427,6 +427,13 @@ void parse_em(void)
                     {
                         switch (em.em_argtype)
                         {
+                            case 0:
+                                /* This is an instruction which would normally
+                                 * take a size, but the size is provided on the
+                                 * stack. We hates them. */
+                                queue_insn_simple(em.em_opcode);
+                                break;
+                                
                             case ilb_ptyp:
                                 queue_insn_ilabel(em.em_opcode, em.em_ilb);
                                 break;
index b1b235f..82fae86 100644 (file)
@@ -371,8 +371,12 @@ static void insn_simple(int opcode)
             );
             break;
 
-        case op_teq: simple_test(EM_wordsize, IR_IFEQ); break;
+        case op_teq: simple_test(    EM_wordsize, IR_IFEQ); break;
         case op_tne: simple_test_neg(EM_wordsize, IR_IFEQ); break;
+        case op_tlt: simple_test(    EM_wordsize, IR_IFLT); break;
+        case op_tge: simple_test_neg(EM_wordsize, IR_IFLT); break;
+        case op_tle: simple_test(    EM_wordsize, IR_IFLE); break;
+        case op_tgt: simple_test_neg(EM_wordsize, IR_IFLE); break;
 
         case op_cai:
         {
@@ -447,6 +451,20 @@ static void insn_simple(int opcode)
             break;
         }
 
+        /* FIXME: These instructions are really complex and barely used
+         * (Modula-2 bitset support, I believe). Leave them until leter. */
+        case op_set:
+        case op_ior:
+        {
+            appendir(
+                new_ir1(
+                    IR_CALL, 0,
+                    new_labelir(".unimplemented")
+                )
+            );
+            break;
+        }
+
         case op_lni:
         {
             /* Increment line number --- ignore. */
@@ -1181,6 +1199,83 @@ static void insn_ivalue(int opcode, arith value)
             break;
         }
 
+        case op_los:
+        {
+            /* Copy an arbitrary amount to the stack. */
+            struct ir* bytes = pop(EM_wordsize);
+            struct ir* address = pop(EM_pointersize);
+
+            materialise_stack();
+            appendir(
+                new_ir1(
+                    IR_STACKADJUST, EM_pointersize,
+                    new_ir1(
+                        IR_NEG, EM_wordsize,
+                        bytes
+                    )
+                )
+            );
+
+            push(
+                new_ir0(
+                    IR_GETSP, EM_pointersize
+                )
+            );
+            push(address);
+            push(bytes);
+            materialise_stack();
+            appendir(
+                new_ir1(
+                    IR_CALL, 0,
+                    new_labelir("memcpy")
+                )
+            );
+            appendir(
+                new_ir1(
+                    IR_STACKADJUST, EM_pointersize,
+                    new_wordir(EM_pointersize*2 + EM_wordsize)
+                )
+            );
+            break;
+        }
+
+        case op_sts:
+        {
+            /* Copy an arbitrary amount from the stack. */
+            struct ir* bytes = pop(EM_wordsize);
+            struct ir* dest = pop(EM_pointersize);
+            struct ir* src;
+
+            materialise_stack();
+            src = appendir(
+                    new_ir0(
+                        IR_GETSP, EM_pointersize
+                    )
+                );
+
+            push(dest);
+            push(src);
+            push(bytes);
+            materialise_stack();
+            appendir(
+                new_ir1(
+                    IR_CALL, 0,
+                    new_labelir("memcpy")
+                )
+            );
+            appendir(
+                new_ir1(
+                    IR_STACKADJUST, EM_pointersize,
+                    new_ir2(
+                        IR_ADD, EM_wordsize,
+                        new_wordir(EM_pointersize*2 + EM_wordsize),
+                        bytes
+                    )
+                )
+            );
+            break;
+        }
+
         case op_lin:
         {
             /* Set line number --- ignore. */