stack[stackptr++] = ir;
}
+/* Returns the size of the top item on the stack. */
+static int peek(int delta)
+{
+ if (stackptr <= delta)
+ return EM_wordsize;
+ else
+ {
+ struct ir* ir = stack[stackptr-1-delta];
+ return ir->size;
+ }
+}
+
static struct ir* pop(int size)
{
if (size < EM_wordsize)
if (size < EM_wordsize)
ir = convertu(ir, size);
#endif
-
if (ir->size != size)
{
if ((size == (EM_wordsize*2)) && (ir->size == EM_wordsize))
struct ir* ptr = pop(EM_pointersize);
int offset = 0;
- /* FIXME: this is awful; need a better way of dealing with
- * non-standard EM sizes. */
if (value > (EM_wordsize*2))
+ {
+ /* We're going to need to do multiple stores; fix the address
+ * so it'll go into a register and we can do maths on it. */
appendir(ptr);
+ }
while (value > 0)
{
- int s;
- if (value > (EM_wordsize*2))
- s = EM_wordsize*2;
- else
+ int s = EM_wordsize*2;
+ if (value < s)
s = value;
push(
struct ir* ptr = pop(EM_pointersize);
int offset = 0;
- /* FIXME: this is awful; need a better way of dealing with
- * non-standard EM sizes. */
- if (value > (EM_wordsize*2))
+ if (value > peek(0))
+ {
+ /* We're going to need to do multiple stores; fix the address
+ * so it'll go into a register and we can do maths on it. */
appendir(ptr);
+ }
while (value > 0)
{
- int s;
- if (value > (EM_wordsize*2))
- s = EM_wordsize*2;
- else
+ struct ir* v = pop(peek(0));
+ int s = v->size;
+ if (value < s)
s = value;
appendir(
store(
s,
ptr, offset,
- pop(s)
+ v
)
);
case op_dup:
{
- struct ir* v = pop(value);
- appendir(v);
- push(v);
- push(v);
+ sequence_point();
+ if ((value == (EM_wordsize*2)) && (peek(0) == EM_wordsize) && (peek(1) == EM_wordsize))
+ {
+ struct ir* v1 = pop(EM_wordsize);
+ struct ir* v2 = pop(EM_wordsize);
+ push(v2);
+ push(v1);
+ push(v2);
+ push(v1);
+ }
+ else
+ {
+ struct ir* v = pop(value);
+ push(v);
+ push(v);
+ }
break;
}
default:
while ((value > 0) && (stackptr > 0))
{
- struct ir* ir = pop(stack[stackptr-1]->size);
- value -= ir->size;
+ int s = peek(0);
+ if (s > value)
+ s = value;
+ pop(s);
+ value -= s;
}
if (value != 0)