From b22780c075ddd4134410cbad5c76680babcd3104 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 23 Oct 2016 22:24:08 +0200 Subject: [PATCH] More opcodes, including the difficult and fairly stupid los/sts. --- mach/powerpc/mcg/table | 4 ++ mach/proto/mcg/parse_em.c | 7 +++ mach/proto/mcg/treebuilder.c | 97 +++++++++++++++++++++++++++++++++++- 3 files changed, 107 insertions(+), 1 deletion(-) diff --git a/mach/powerpc/mcg/table b/mach/powerpc/mcg/table index 2c3565a73..448e1123e 100644 --- a/mach/powerpc/mcg/table +++ b/mach/powerpc/mcg/table @@ -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; diff --git a/mach/proto/mcg/parse_em.c b/mach/proto/mcg/parse_em.c index 9551ecd02..26754b1e1 100644 --- a/mach/proto/mcg/parse_em.c +++ b/mach/proto/mcg/parse_em.c @@ -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; diff --git a/mach/proto/mcg/treebuilder.c b/mach/proto/mcg/treebuilder.c index b1b235f30..82fae8655 100644 --- a/mach/proto/mcg/treebuilder.c +++ b/mach/proto/mcg/treebuilder.c @@ -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. */ -- 2.34.1