Add a pile of new instructions used by Pascal; I'm going to need to think about
how locals and the local base are handled.
This commit is contained in:
parent
358c44de35
commit
5ad3aa8595
|
@ -243,6 +243,10 @@ static void parse_pseu(void)
|
|||
data_offset(dlabel_to_str(em.em_dlb), em.em_off, ro);
|
||||
break;
|
||||
|
||||
case sof_ptyp:
|
||||
data_offset(strdup(em.em_dnam), em.em_off, ro);
|
||||
break;
|
||||
|
||||
case ilb_ptyp:
|
||||
{
|
||||
const char* label = ilabel_to_str(em.em_ilb);
|
||||
|
@ -279,6 +283,18 @@ static void parse_pseu(void)
|
|||
data_bss(EM_bsssize, em.em_cst);
|
||||
break;
|
||||
|
||||
case ico_ptyp:
|
||||
case uco_ptyp:
|
||||
{
|
||||
arith val = atol(em.em_string);
|
||||
data_int(val, em.em_size, false);
|
||||
break;
|
||||
}
|
||||
|
||||
case sof_ptyp:
|
||||
data_offset(strdup(em.em_dnam), em.em_off, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
unknown_type("bss");
|
||||
}
|
||||
|
|
|
@ -126,6 +126,18 @@ PATTERNS
|
|||
emit "addi sp, sp, $delta"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = GETFP4
|
||||
emit "mr %out, fp"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = FPTOARGS4(GETFP4)
|
||||
emit "addi %out, fp, 8"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = FPTOARGS4(in:(int)reg)
|
||||
emit "addi %out, %in, 8"
|
||||
cost 4;
|
||||
|
||||
|
||||
|
||||
/* Memory operations */
|
||||
|
@ -354,6 +366,20 @@ PATTERNS
|
|||
|
||||
|
||||
|
||||
/* Booleans */
|
||||
|
||||
out:(int)reg = IFEQ4(in:(cr)cr)
|
||||
emit "mfcr %out" /* get cr0 */
|
||||
emit "rlwinmi %out, %out, 32-2, 2, 31" /* extract just EQ */
|
||||
cost 8;
|
||||
|
||||
out:(int)reg = IFEQ4(in:(int)reg)
|
||||
emit "cntlzw %out, %in" /* returns 0..32 */
|
||||
emit "rlwinmi %out, %out, 32-5, 5, 31" /* if 32, return 1, otherwise 0 */
|
||||
cost 8;
|
||||
|
||||
|
||||
|
||||
/* Conversions */
|
||||
|
||||
out:(int)reg = CIU44(in:(int)reg)
|
||||
|
@ -406,6 +432,10 @@ PATTERNS
|
|||
emit "neg %out, %left"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = OR4(left:(int)reg, right:(int)reg)
|
||||
emit "or %out, %right, %left"
|
||||
cost 4;
|
||||
|
||||
out:(int)reg = EOR4(left:(int)reg, right:(int)reg)
|
||||
emit "xor %out, %right, %left"
|
||||
cost 4;
|
||||
|
|
|
@ -204,6 +204,15 @@ static void insn_simple(int opcode)
|
|||
);
|
||||
break;
|
||||
|
||||
case op_teq:
|
||||
push(
|
||||
new_ir1(
|
||||
IR_IFEQ, EM_wordsize,
|
||||
pop(EM_wordsize)
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case op_cai:
|
||||
{
|
||||
struct ir* dest = pop(EM_pointersize);
|
||||
|
@ -242,6 +251,35 @@ static void insn_simple(int opcode)
|
|||
break;
|
||||
}
|
||||
|
||||
case op_lim:
|
||||
{
|
||||
push(
|
||||
new_ir1(
|
||||
IR_LOAD, 2,
|
||||
new_labelir(".ignmask")
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case op_sim:
|
||||
{
|
||||
appendir(
|
||||
new_ir2(
|
||||
IR_STORE, 2,
|
||||
new_labelir(".ignmask"),
|
||||
pop(EM_wordsize)
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case op_lni:
|
||||
{
|
||||
/* Increment line number --- ignore. */
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fatal("treebuilder: unknown simple instruction '%s'",
|
||||
em_mnem[opcode - sp_fmnem]);
|
||||
|
@ -561,6 +599,7 @@ static void insn_ivalue(int opcode, arith value)
|
|||
break;
|
||||
|
||||
case op_cmu:
|
||||
case op_cms:
|
||||
push(
|
||||
tristate_compare(value, IR_COMPAREU)
|
||||
);
|
||||
|
@ -717,6 +756,92 @@ static void insn_ivalue(int opcode, arith value)
|
|||
break;
|
||||
}
|
||||
|
||||
case op_sar:
|
||||
case op_lar:
|
||||
case op_aar:
|
||||
{
|
||||
const char* helper;
|
||||
if (value != EM_wordsize)
|
||||
fatal("sar/lar/aar are only supported when using "
|
||||
"word-size descriptors");
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case op_sar: helper = ".sar4"; break;
|
||||
case op_lar: helper = ".lar4"; break;
|
||||
case op_aar: helper = ".aar4"; break;
|
||||
}
|
||||
|
||||
materialise_stack();
|
||||
appendir(
|
||||
new_ir1(
|
||||
IR_CALL, 0,
|
||||
new_labelir(helper)
|
||||
)
|
||||
);
|
||||
push(
|
||||
new_ir0(
|
||||
IR_GETRET, EM_wordsize
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case op_lxl:
|
||||
{
|
||||
struct ir* ir;
|
||||
|
||||
/* Walk the static chain. */
|
||||
|
||||
ir = new_ir0(
|
||||
IR_GETFP, EM_pointersize
|
||||
);
|
||||
|
||||
while (value--)
|
||||
{
|
||||
ir = new_ir1(
|
||||
IR_CHAINFP, EM_pointersize,
|
||||
ir
|
||||
);
|
||||
}
|
||||
|
||||
push(ir);
|
||||
break;
|
||||
}
|
||||
|
||||
case op_lxa:
|
||||
{
|
||||
struct ir* ir;
|
||||
|
||||
/* Walk the static chain. */
|
||||
|
||||
ir = new_ir0(
|
||||
IR_GETFP, EM_pointersize
|
||||
);
|
||||
|
||||
while (value--)
|
||||
{
|
||||
ir = new_ir1(
|
||||
IR_CHAINFP, EM_pointersize,
|
||||
ir
|
||||
);
|
||||
}
|
||||
|
||||
push(
|
||||
new_ir1(
|
||||
IR_FPTOARGS, EM_pointersize,
|
||||
ir
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case op_lin:
|
||||
{
|
||||
/* Set line number --- ignore. */
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fatal("treebuilder: unknown ivalue instruction '%s'",
|
||||
em_mnem[opcode - sp_fmnem]);
|
||||
|
@ -783,6 +908,12 @@ static void insn_lvalue(int opcode, const char* label, arith offset)
|
|||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case op_fil:
|
||||
{
|
||||
/* Set filename --- ignore. */
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fatal("treebuilder: unknown lvalue instruction '%s'",
|
||||
|
|
|
@ -86,4 +86,7 @@ V RET
|
|||
S STACKADJUST
|
||||
S GETRET
|
||||
S SETRET
|
||||
S GETFP
|
||||
S CHAINFP
|
||||
S FPTOARGS
|
||||
|
||||
|
|
Loading…
Reference in a new issue