multiplication
This commit is contained in:
parent
12efe0056b
commit
d87b2fed28
3 changed files with 18 additions and 19 deletions
|
|
@ -13,6 +13,8 @@ enum op {
|
|||
ADDI, // ra += imm
|
||||
SUB, // ra -= rb
|
||||
SUBI, // ra -= imm
|
||||
MUL, // ra *= rb
|
||||
MULI, // ra *= imm
|
||||
NEG, // ra = -ra (= ~ra + 1) (rb not used!)
|
||||
NOT, // ra = ~ra (rb not used!)
|
||||
MOV, // ra = rb
|
||||
|
|
@ -72,6 +74,8 @@ enum reg {
|
|||
#define GEN_ADDI(my_ra, i) ((struct insn) { .op = ADDI, .ra = my_ra, .rb = 0, .imm = i })
|
||||
#define GEN_SUB(my_ra, my_rb) ((struct insn) { .op = SUB, .ra = my_ra, .rb = my_rb })
|
||||
#define GEN_SUBI(my_ra, i) ((struct insn) { .op = SUBI, .ra = my_ra, .rb = 0, .imm = i })
|
||||
#define GEN_MUL(my_ra, my_rb) ((struct insn) { .op = MUL, .ra = my_ra, .rb = my_rb })
|
||||
#define GEN_MULI(my_ra, i) ((struct insn) { .op = MULI, .ra = my_ra, .rb = 0, .imm = i })
|
||||
#define GEN_NEG(my_ra) ((struct insn) { .op = NEG, .ra = my_ra, .rb = 0 })
|
||||
#define GEN_NOT(my_ra) ((struct insn) { .op = NOT, .ra = my_ra, .rb = 0 })
|
||||
#define GEN_ANDI(my_ra, i) ((struct insn) { .op = ANDI, .ra = my_ra, .rb = 0, .imm = i })
|
||||
|
|
|
|||
|
|
@ -36,25 +36,8 @@ static void app_jitpaint_step(void *self) {
|
|||
// input: R0: x, R1: y, R2: t
|
||||
// output: R0: r, R1: g, R2: b
|
||||
struct insn insns[] = {
|
||||
GEN_ADD(R0, R2),
|
||||
GEN_SUB(R1, R2),
|
||||
GEN_SRLI(R0, 3),
|
||||
GEN_SRLI(R1, 3),
|
||||
GEN_ADD(R0, R1),
|
||||
GEN_ANDI(R0, 1),
|
||||
|
||||
GEN_MOV(R1, R0),
|
||||
GEN_SLLI(R1, 1),
|
||||
GEN_OR(R0, R1),
|
||||
|
||||
GEN_MOV(R1, R0),
|
||||
GEN_SLLI(R1, 2),
|
||||
GEN_OR(R0, R1),
|
||||
|
||||
GEN_MOV(R1, R0),
|
||||
GEN_SLLI(R1, 4),
|
||||
GEN_OR(R0, R1),
|
||||
|
||||
GEN_MUL(R0, R1),
|
||||
GEN_SRLI(R0, 8),
|
||||
GEN_MOV(R1, R0),
|
||||
GEN_MOV(R2, R0),
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,18 @@ uint8_t *jit_compile_single(struct insn *insn, uint8_t *mem) {
|
|||
mem = jit_compile_single(&help, mem);
|
||||
}
|
||||
break;
|
||||
case MUL:
|
||||
*mem++ = OPBYTE(0x48, x86a, x86b);
|
||||
*mem++ = 0x0f;
|
||||
*mem++ = 0xaf;
|
||||
*mem++ = MODRM(0xc0, x86a, x86b);
|
||||
break;
|
||||
case MULI:
|
||||
// using same register twice because we do in-place
|
||||
*mem++ = OPBYTE(0x48, x86a, x86a);
|
||||
*mem++ = 69;
|
||||
*mem++ = MODRM(0xc0, x86a, x86a);
|
||||
break;
|
||||
case ANDI:
|
||||
// This is the worst case, when the operand has to be 8 bytes big. There are way better encodings. the insn also sign-extends.
|
||||
help = GEN_MOVI(RSCRATCH, insn->imm);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue