More opcodes, including the difficult and fairly stupid los/sts.

This commit is contained in:
David Given 2016-10-23 22:24:08 +02:00
parent abd0cedd61
commit b22780c075
3 changed files with 107 additions and 1 deletions

View 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;

View 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;

View 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. */