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);
|
data_offset(dlabel_to_str(em.em_dlb), em.em_off, ro);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case sof_ptyp:
|
||||||
|
data_offset(strdup(em.em_dnam), em.em_off, ro);
|
||||||
|
break;
|
||||||
|
|
||||||
case ilb_ptyp:
|
case ilb_ptyp:
|
||||||
{
|
{
|
||||||
const char* label = ilabel_to_str(em.em_ilb);
|
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);
|
data_bss(EM_bsssize, em.em_cst);
|
||||||
break;
|
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:
|
default:
|
||||||
unknown_type("bss");
|
unknown_type("bss");
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,18 @@ PATTERNS
|
||||||
emit "addi sp, sp, $delta"
|
emit "addi sp, sp, $delta"
|
||||||
cost 4;
|
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 */
|
/* 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 */
|
/* Conversions */
|
||||||
|
|
||||||
out:(int)reg = CIU44(in:(int)reg)
|
out:(int)reg = CIU44(in:(int)reg)
|
||||||
|
@ -406,6 +432,10 @@ PATTERNS
|
||||||
emit "neg %out, %left"
|
emit "neg %out, %left"
|
||||||
cost 4;
|
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)
|
out:(int)reg = EOR4(left:(int)reg, right:(int)reg)
|
||||||
emit "xor %out, %right, %left"
|
emit "xor %out, %right, %left"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
|
@ -204,6 +204,15 @@ static void insn_simple(int opcode)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case op_teq:
|
||||||
|
push(
|
||||||
|
new_ir1(
|
||||||
|
IR_IFEQ, EM_wordsize,
|
||||||
|
pop(EM_wordsize)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
case op_cai:
|
case op_cai:
|
||||||
{
|
{
|
||||||
struct ir* dest = pop(EM_pointersize);
|
struct ir* dest = pop(EM_pointersize);
|
||||||
|
@ -242,6 +251,35 @@ static void insn_simple(int opcode)
|
||||||
break;
|
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:
|
default:
|
||||||
fatal("treebuilder: unknown simple instruction '%s'",
|
fatal("treebuilder: unknown simple instruction '%s'",
|
||||||
em_mnem[opcode - sp_fmnem]);
|
em_mnem[opcode - sp_fmnem]);
|
||||||
|
@ -561,6 +599,7 @@ static void insn_ivalue(int opcode, arith value)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case op_cmu:
|
case op_cmu:
|
||||||
|
case op_cms:
|
||||||
push(
|
push(
|
||||||
tristate_compare(value, IR_COMPAREU)
|
tristate_compare(value, IR_COMPAREU)
|
||||||
);
|
);
|
||||||
|
@ -717,6 +756,92 @@ static void insn_ivalue(int opcode, arith value)
|
||||||
break;
|
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:
|
default:
|
||||||
fatal("treebuilder: unknown ivalue instruction '%s'",
|
fatal("treebuilder: unknown ivalue instruction '%s'",
|
||||||
em_mnem[opcode - sp_fmnem]);
|
em_mnem[opcode - sp_fmnem]);
|
||||||
|
@ -783,6 +908,12 @@ static void insn_lvalue(int opcode, const char* label, arith offset)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case op_fil:
|
||||||
|
{
|
||||||
|
/* Set filename --- ignore. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fatal("treebuilder: unknown lvalue instruction '%s'",
|
fatal("treebuilder: unknown lvalue instruction '%s'",
|
||||||
|
|
|
@ -86,4 +86,7 @@ V RET
|
||||||
S STACKADJUST
|
S STACKADJUST
|
||||||
S GETRET
|
S GETRET
|
||||||
S SETRET
|
S SETRET
|
||||||
|
S GETFP
|
||||||
|
S CHAINFP
|
||||||
|
S FPTOARGS
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue