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"
|
emit "add sp, sp, %in"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
|
STACKADJUST.I(NEG.I(in:(int)reg))
|
||||||
|
emit "subf sp, %in, sp"
|
||||||
|
cost 4;
|
||||||
|
|
||||||
out:(int)reg = GETFP.I
|
out:(int)reg = GETFP.I
|
||||||
emit "mr %out, fp"
|
emit "mr %out, fp"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
|
@ -427,6 +427,13 @@ void parse_em(void)
|
||||||
{
|
{
|
||||||
switch (em.em_argtype)
|
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:
|
case ilb_ptyp:
|
||||||
queue_insn_ilabel(em.em_opcode, em.em_ilb);
|
queue_insn_ilabel(em.em_opcode, em.em_ilb);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -371,8 +371,12 @@ static void insn_simple(int opcode)
|
||||||
);
|
);
|
||||||
break;
|
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_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:
|
case op_cai:
|
||||||
{
|
{
|
||||||
|
@ -447,6 +451,20 @@ static void insn_simple(int opcode)
|
||||||
break;
|
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:
|
case op_lni:
|
||||||
{
|
{
|
||||||
/* Increment line number --- ignore. */
|
/* Increment line number --- ignore. */
|
||||||
|
@ -1181,6 +1199,83 @@ static void insn_ivalue(int opcode, arith value)
|
||||||
break;
|
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:
|
case op_lin:
|
||||||
{
|
{
|
||||||
/* Set line number --- ignore. */
|
/* Set line number --- ignore. */
|
||||||
|
|
Loading…
Reference in a new issue