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:
David Given 2016-10-29 12:48:05 +02:00
parent 68419da235
commit 61349389fb
4 changed files with 107 additions and 11 deletions

View file

@ -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"

View file

@ -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);

View file

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

View file

@ -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