More opcodes. sti can now cope with non-standard sizes (really need a better
fix for this). Hack in crude support for mismatched stack pushes and pops (ints vs longs).
This commit is contained in:
parent
68419da235
commit
61349389fb
|
@ -417,6 +417,19 @@ PATTERNS
|
|||
emit "bl .fromui2d"
|
||||
cost 4;
|
||||
|
||||
out:(lret)reg = FROMIPAIR.L(in1:(int)reg, in2:(int)reg)
|
||||
emit "mr %out.0, %in1"
|
||||
emit "mr %out.1, %in2"
|
||||
cost 8;
|
||||
|
||||
out:(int)reg = FROML0.I(in:(long)reg)
|
||||
emit "mr %out, %in.0"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = FROML1.I(in:(long)reg)
|
||||
emit "mr %out, %in.1"
|
||||
cost 4;
|
||||
|
||||
|
||||
|
||||
/* Locals */
|
||||
|
@ -448,6 +461,11 @@ PATTERNS
|
|||
emit "b $addr"
|
||||
cost 4;
|
||||
|
||||
JUMP(dest:(int)reg)
|
||||
emit "mtspr ctr, %dest"
|
||||
emit "bcctrl 20, 0, 0"
|
||||
cost 8;
|
||||
|
||||
CJUMPEQ(value:(cr)cr, PAIR(true:BLOCK.I, false:BLOCK.I))
|
||||
emit "bc 12, 2, $true" /* IFTRUE EQ */
|
||||
emit "b $false"
|
||||
|
|
|
@ -64,7 +64,8 @@ void data_float(const char* data, size_t size, bool is_ro)
|
|||
emit_header(is_ro ? SECTION_ROM : SECTION_DATA);
|
||||
assert((size == 4) || (size == 8));
|
||||
|
||||
if (float_cst(data, size, (char*) buffer))
|
||||
i = float_cst(data, size, (char*) buffer);
|
||||
if ((i != 0) && (i != 2)) /* 2 == overflow */
|
||||
fatal("cannot parse floating point constant %s sz %d", data, size);
|
||||
|
||||
fprintf(outputfile, "\t!float %s sz %d\n", data, size);
|
||||
|
|
|
@ -59,7 +59,37 @@ static struct ir* pop(int size)
|
|||
#endif
|
||||
|
||||
if (ir->size != size)
|
||||
fatal("expected an item on stack of size %d, but got %d\n", size, ir->size);
|
||||
{
|
||||
if ((size == (EM_wordsize*2)) && (ir->size == EM_wordsize))
|
||||
{
|
||||
/* Tried to read a long, but we got an int. Assemble the long
|
||||
* out of two ints. Note that EM doesn't specify an order. */
|
||||
return
|
||||
new_ir2(
|
||||
IR_FROMIPAIR, size,
|
||||
ir,
|
||||
pop(EM_wordsize)
|
||||
);
|
||||
}
|
||||
else if ((size == EM_wordsize) && (ir->size == (EM_wordsize*2)))
|
||||
{
|
||||
/* Tried to read an int, but we got a long. */
|
||||
push(
|
||||
new_ir1(
|
||||
IR_FROML1, EM_wordsize,
|
||||
ir
|
||||
)
|
||||
);
|
||||
|
||||
return
|
||||
new_ir1(
|
||||
IR_FROML0, EM_wordsize,
|
||||
ir
|
||||
);
|
||||
}
|
||||
else
|
||||
fatal("expected an item on stack of size %d, but got %d\n", size, ir->size);
|
||||
}
|
||||
return ir;
|
||||
}
|
||||
}
|
||||
|
@ -864,15 +894,34 @@ static void insn_ivalue(int opcode, arith value)
|
|||
case op_sti:
|
||||
{
|
||||
struct ir* ptr = pop(EM_pointersize);
|
||||
struct ir* val = pop(value);
|
||||
int offset = 0;
|
||||
|
||||
appendir(
|
||||
store(
|
||||
value,
|
||||
ptr, 0,
|
||||
val
|
||||
)
|
||||
);
|
||||
/* FIXME: this is awful; need a better way of dealing with
|
||||
* non-standard EM sizes. */
|
||||
if (value > (EM_wordsize*2))
|
||||
appendir(ptr);
|
||||
|
||||
while (value > 0)
|
||||
{
|
||||
int s;
|
||||
if (value > (EM_wordsize*2))
|
||||
s = EM_wordsize*2;
|
||||
else
|
||||
s = value;
|
||||
|
||||
appendir(
|
||||
store(
|
||||
s,
|
||||
ptr, offset,
|
||||
pop(s)
|
||||
)
|
||||
);
|
||||
|
||||
value -= s;
|
||||
offset += s;
|
||||
}
|
||||
|
||||
assert(value == 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1483,6 +1532,31 @@ static void insn_lvalue(int opcode, const char* label, arith offset)
|
|||
);
|
||||
break;
|
||||
|
||||
case op_gto:
|
||||
{
|
||||
struct ir* descriptor = pop(EM_pointersize);
|
||||
|
||||
appendir(
|
||||
new_ir1(
|
||||
IR_SETSP, EM_pointersize,
|
||||
load(EM_pointersize, descriptor, EM_pointersize*2)
|
||||
)
|
||||
);
|
||||
appendir(
|
||||
new_ir1(
|
||||
IR_SETFP, EM_pointersize,
|
||||
load(EM_pointersize, descriptor, EM_pointersize*1)
|
||||
)
|
||||
);
|
||||
appendir(
|
||||
new_ir1(
|
||||
IR_JUMP, 0,
|
||||
load(EM_pointersize, descriptor, EM_pointersize*0)
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case op_fil:
|
||||
{
|
||||
/* Set filename --- ignore. */
|
||||
|
|
|
@ -71,6 +71,9 @@ S ?=I. FROMSI
|
|||
S ?=L. FROMSL
|
||||
S ?=F. FROMF
|
||||
S ?=D. FROMD
|
||||
S L=II FROMIPAIR
|
||||
S I=L. FROML0
|
||||
S I=L. FROML1
|
||||
|
||||
# The H versions are only used if wordsize > 2
|
||||
S I=I. EXTENDB
|
||||
|
|
Loading…
Reference in a new issue