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:
David Given 2016-10-15 13:07:59 +02:00
parent 358c44de35
commit 5ad3aa8595
4 changed files with 180 additions and 0 deletions

View file

@ -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);
@ -277,6 +281,18 @@ static void parse_pseu(void)
{
case cst_ptyp:
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:

View file

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

View file

@ -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]);
@ -784,6 +909,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'",
em_mnem[opcode - sp_fmnem]);

View file

@ -86,4 +86,7 @@ V RET
S STACKADJUST
S GETRET
S SETRET
S GETFP
S CHAINFP
S FPTOARGS