More opcodes.

This commit is contained in:
David Given 2016-10-22 20:32:51 +02:00
parent 2d52b1fdaa
commit 11b0bc1055
3 changed files with 90 additions and 43 deletions

View file

@ -464,12 +464,12 @@ PATTERNS
out:(int)reg = IFEQ4(in:(cr)cr)
emit "mfcr %out" /* get cr0 */
emit "rlwinmi %out, %out, 32-2, 2, 31" /* extract just EQ */
emit "rlwinm %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 */
emit "rlwinm %out, %out, [32-5], 5, 31" /* if 32, return 1, otherwise 0 */
cost 8;
@ -527,6 +527,12 @@ PATTERNS
emit "subf %out, %out, %left"
cost 12;
out:(int)reg = MODU4(left:(int)reg, right:(int)reg)
emit "divwu %out, %left, %right"
emit "mullw %out, %out, %right"
emit "subf %out, %out, %left"
cost 12;
ALUR(MUL4, "mullw")
ALUCC(MUL4, "mulli")
@ -535,10 +541,17 @@ PATTERNS
ALUR(ASL4, "slw")
ALUR(LSL4, "slw")
out:(int)reg = NEG4(left:(int)reg)
emit "neg %out, %left"
cost 4;
out:(int)reg = NOT4(left:(int)reg)
emit "cntlzw %out, %left"
emit "rlwinm %out, %out, 32-5, 5, 31"
cost 8;
ALUR(AND4, "and")
ALUCC(AND4, "andi.")

View file

@ -178,6 +178,14 @@ static struct ir* tristate_compare(int size, int opcode)
return compare(left, right, size, opcode);
}
static struct ir* tristate_compare0(int size, int opcode)
{
struct ir* right = new_wordir(0);
struct ir* left = pop(size);
return compare(left, right, size, opcode);
}
static void simple_convert(int opcode)
{
struct ir* destsize = pop(EM_wordsize);
@ -193,6 +201,60 @@ static void simple_convert(int opcode)
);
}
static void simple_branch2(int opcode, int size,
struct basicblock* truebb, struct basicblock* falsebb,
int irop)
{
struct ir* right = pop(size);
struct ir* left = pop(size);
materialise_stack();
appendir(
new_ir2(
irop, 0,
compare(left, right, size, IR_COMPARES1),
new_ir2(
IR_PAIR, 0,
new_bbir(truebb),
new_bbir(falsebb)
)
)
);
}
static void compare0_branch2(int opcode,
struct basicblock* truebb, struct basicblock* falsebb,
int irop)
{
push(
new_wordir(0)
);
simple_branch2(opcode, EM_wordsize, truebb, falsebb, irop);
}
static void simple_test(int size, int irop)
{
push(
new_ir1(
irop, EM_wordsize,
tristate_compare0(size, IR_COMPARES1)
)
);
}
static void simple_test_neg(int size, int irop)
{
simple_test(size, irop);
push(
new_ir1(
IR_NOT, EM_wordsize,
pop(EM_wordsize)
)
);
}
static void insn_simple(int opcode)
{
switch (opcode)
@ -224,14 +286,8 @@ static void insn_simple(int opcode)
);
break;
case op_teq:
push(
new_ir1(
IR_IFEQ, EM_wordsize,
pop(EM_wordsize)
)
);
break;
case op_teq: simple_test(EM_wordsize, IR_IFEQ); break;
case op_tne: simple_test_neg(EM_wordsize, IR_IFEQ); break;
case op_cai:
{
@ -318,38 +374,6 @@ static void insn_simple(int opcode)
}
}
static void simple_branch2(int opcode, int size,
struct basicblock* truebb, struct basicblock* falsebb,
int irop)
{
struct ir* right = pop(size);
struct ir* left = pop(size);
materialise_stack();
appendir(
new_ir2(
irop, 0,
compare(left, right, size, IR_COMPARES1),
new_ir2(
IR_PAIR, 0,
new_bbir(truebb),
new_bbir(falsebb)
)
)
);
}
static void compare0_branch2(int opcode,
struct basicblock* truebb, struct basicblock* falsebb,
int irop)
{
push(
new_wordir(0)
);
simple_branch2(opcode, EM_wordsize, truebb, falsebb, irop);
}
static void insn_bvalue(int opcode, struct basicblock* leftbb, struct basicblock* rightbb)
{
switch (opcode)
@ -490,6 +514,7 @@ static void insn_ivalue(int opcode, arith value)
case op_mlu: simple_alu2(opcode, value, IR_MUL); break;
case op_slu: simple_alu2(opcode, value, IR_LSL); break;
case op_sru: simple_alu2(opcode, value, IR_LSR); break;
case op_rmu: simple_alu2(opcode, value, IR_MODU); break;
case op_dvu: simple_alu2(opcode, value, IR_DIVU); break;
case op_and: simple_alu2(opcode, value, IR_AND); break;
@ -595,6 +620,14 @@ static void insn_ivalue(int opcode, arith value)
);
break;
case op_zrf:
{
struct ir* ir = new_constir(value, 0);
ir->opcode = IR_CONSTF;
push(ir);
break;
}
case op_loe:
push(
new_ir1(

View file

@ -32,6 +32,7 @@ S MUL
S DIV
S DIVU
S MOD
S MODU
S NEG
S ADDF
@ -96,7 +97,7 @@ S COMPAREF2
S COMPAREF4
S COMPAREF8
# Boolean comparisons
# Tristate to boolean conversion
S IFEQ
S IFLT
S IFLE