More opcodes, including the difficult and fairly stupid los/sts.
This commit is contained in:
parent
abd0cedd61
commit
b22780c075
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in a new issue