Add MIPS codegen tests

This commit is contained in:
David Guillen Fandos 2022-01-07 23:05:05 +01:00
parent 81649a2c80
commit 8c4196d19e
5 changed files with 348 additions and 46 deletions

View File

@ -19,38 +19,38 @@
typedef enum
{
mips_reg_zero,
mips_reg_at,
mips_reg_v0,
mips_reg_v1,
mips_reg_a0,
mips_reg_a1,
mips_reg_a2,
mips_reg_a3,
mips_reg_t0,
mips_reg_t1,
mips_reg_t2,
mips_reg_t3,
mips_reg_t4,
mips_reg_t5,
mips_reg_t6,
mips_reg_t7,
mips_reg_s0,
mips_reg_s1,
mips_reg_s2,
mips_reg_s3,
mips_reg_s4,
mips_reg_s5,
mips_reg_s6,
mips_reg_s7,
mips_reg_t8,
mips_reg_t9,
mips_reg_k0,
mips_reg_k1,
mips_reg_gp,
mips_reg_sp,
mips_reg_fp,
mips_reg_ra
mips_reg_zero = 0,
mips_reg_at = 1,
mips_reg_v0 = 2,
mips_reg_v1 = 3,
mips_reg_a0 = 4,
mips_reg_a1 = 5,
mips_reg_a2 = 6,
mips_reg_a3 = 7,
mips_reg_t0 = 8,
mips_reg_t1 = 9,
mips_reg_t2 = 10,
mips_reg_t3 = 11,
mips_reg_t4 = 12,
mips_reg_t5 = 13,
mips_reg_t6 = 14,
mips_reg_t7 = 15,
mips_reg_s0 = 16,
mips_reg_s1 = 17,
mips_reg_s2 = 18,
mips_reg_s3 = 19,
mips_reg_s4 = 20,
mips_reg_s5 = 21,
mips_reg_s6 = 22,
mips_reg_s7 = 23,
mips_reg_t8 = 24,
mips_reg_t9 = 25,
mips_reg_k0 = 26,
mips_reg_k1 = 27,
mips_reg_gp = 28,
mips_reg_sp = 29,
mips_reg_fp = 30,
mips_reg_ra = 31
} mips_reg_number;
typedef enum
@ -216,12 +216,6 @@ typedef enum
#define mips_emit_xor(rd, rs, rt) \
mips_emit_special(xor, rs, rt, rd, 0) \
#define mips_emit_add(rd, rs, rt) \
mips_emit_special(and, rs, rt, rd, 0) \
#define mips_emit_sub(rd, rs, rt) \
mips_emit_special(sub, rs, rt, rd, 0) \
#define mips_emit_and(rd, rs, rt) \
mips_emit_special(and, rs, rt, rd, 0) \
@ -359,10 +353,10 @@ typedef enum
#define mips_emit_ins(rt, rs, pos, size) \
mips_emit_special3(ins, rs, rt, (pos + size - 1), pos) \
#define mips_emit_seb(rt, rd) \
#define mips_emit_seb(rd, rt) \
mips_emit_special3(bshfl, 0, rt, rd, mips_bshfl_seb) \
#define mips_emit_seh(rt, rd) \
#define mips_emit_seh(rd, rt) \
mips_emit_special3(bshfl, 0, rt, rd, mips_bshfl_seh) \
@ -407,6 +401,6 @@ typedef enum
mips_emit_regimm(bltz, rs, offset) \
#define mips_emit_nop() \
mips_emit_sll(reg_zero, reg_zero, 0) \
mips_emit_sll(mips_reg_zero, mips_reg_zero, 0) \

View File

@ -1904,8 +1904,8 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 address)
#define extract_bits(rt, rs, pos, size) \
mips_emit_ext(rt, rs, pos, size)
// Extends signed byte to u32
#define extend_byte_signed(rt, rs) \
mips_emit_seb(rt, rs)
#define extend_byte_signed(rd, rs) \
mips_emit_seb(rd, rs)
// Rotates a word using a temp reg if necessary
#define rotate_right(rdest, rsrc, rtemp, amount) \
mips_emit_rotr(rdest, rsrc, amount);
@ -1933,9 +1933,9 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 address)
mips_emit_sll(rt, rs, 32 - ((pos) + (size))); \
mips_emit_srl(rt, rt, 32 - (size))
// Extends signed byte to u32
#define extend_byte_signed(rt, rs) \
mips_emit_sll(rt, rs, 24); \
mips_emit_sra(rt, rt, 24)
#define extend_byte_signed(rd, rs) \
mips_emit_sll(rd, rs, 24); \
mips_emit_sra(rd, rd, 24)
// Rotates a word (uses temp reg)
#define rotate_right(rdest, rsrc, rtemp, amount) \
mips_emit_sll(rtemp, rsrc, 32 - (amount)); \

View File

@ -1,5 +1,6 @@
ARMV8PFX=/opt/buildroot-armv8el-uclibc/bin/aarch64-buildroot-linux-uclibc
MIPS32PFX=/opt/buildroot-mipsel32-o32-uclibc/bin/mipsel-buildroot-linux-uclibc
all:
gcc -o arm64gen arm64gen.c -ggdb -I../arm/
@ -8,5 +9,11 @@ all:
$(ARMV8PFX)-objcopy -O binary bytecoderef.o bytecoderef.bin
@ cmp bytecoderef.bin bytecode.bin || echo "Bytecode mismatch"
@ cmp bytecoderef.bin bytecode.bin && echo "Test passed!"
gcc -o mipsgen mipsgen.c -ggdb -I../mips/
./mipsgen > bytecode.bin
$(MIPS32PFX)-as -EL -o bytecoderef.o mipsgen.S
$(MIPS32PFX)-objcopy -j .text -O binary bytecoderef.o bytecoderef.bin
@ cmp bytecoderef.bin bytecode.bin || echo "Bytecode mismatch"
@ cmp bytecoderef.bin bytecode.bin && echo "Test passed!"

180
tests/mipsgen.S Normal file
View File

@ -0,0 +1,180 @@
.set mips32r2
.set noreorder
.text
nop
nop
# Generic MIPS insts
addu $4, $5, $6
addu $29, $31, $20
subu $4, $5, $6
subu $29, $31, $20
xor $4, $5, $6
xor $29, $31, $20
and $4, $5, $6
and $29, $31, $20
or $4, $5, $6
or $29, $31, $20
nor $4, $5, $6
nor $29, $31, $20
slt $4, $5, $6
slt $29, $31, $20
sltu $4, $5, $6
sltu $29, $31, $20
sllv $4, $5, $6
sllv $29, $31, $20
srlv $4, $5, $6
srlv $29, $31, $20
srav $4, $5, $6
srav $29, $31, $20
rotrv $4, $5, $6
rotrv $29, $31, $20
sll $4, $5, 0
srl $4, $5, 0
sra $4, $5, 0
rotr $4, $5, 0
sll $4, $5, 1
srl $4, $5, 1
sra $4, $5, 1
rotr $4, $5, 1
sll $4, $5, 30
srl $4, $5, 30
sra $4, $5, 30
rotr $4, $5, 30
sll $4, $5, 31
srl $4, $5, 31
sra $4, $5, 31
rotr $4, $5, 31
lui $4, 0xFFFF
lui $4, 0x8000
lui $4, 0
lui $4, 1
addiu $4, $22, -1
xori $4, $22, 0xFFFF
ori $4, $22, 0xFFFF
andi $4, $22, 0xFFFF
slti $4, $22, -1
sltiu $4, $22, -1
addiu $4, $22, 0
xori $4, $22, 0
ori $4, $22, 0
andi $4, $22, 0
slti $4, $22, 0
sltiu $4, $22, 0
addiu $4, $22, 1
xori $4, $22, 1
ori $4, $22, 1
andi $4, $22, 1
slti $4, $22, 1
sltiu $4, $22, 1
addiu $4, $22, 0x8000
xori $4, $22, 0x8000
ori $4, $22, 0x8000
andi $4, $22, 0x8000
slti $4, $22, 0x8000
sltiu $4, $22, 0x8000
addiu $4, $22, 0x7FFF
xori $4, $22, 0x7FFF
ori $4, $22, 0x7FFF
andi $4, $22, 0x7FFF
slti $4, $22, 0x7FFF
sltiu $4, $22, 0x7FFF
mflo $7
mflo $30
mfhi $7
mfhi $30
mtlo $7
mtlo $30
mthi $7
mthi $30
mult $6, $7
mult $18, $20
multu $6, $7
multu $18, $20
div $0, $6, $7
div $0, $18, $20
divu $0, $6, $7
divu $0, $18, $20
jr $5
jr $31
jalr $5
jalr $20
bltzal $4, 1f
bltzal $20, 1f
bgezal $4, 1f
bgezal $20, 1f
bltz $4, 1f
bltz $20, 1f
1:
lb $4, ($5)
lbu $4, ($5)
lh $4, ($5)
lhu $4, ($5)
lw $4, ($5)
lb $4, 1($5)
lbu $4, 1($5)
lh $4, 1($5)
lhu $4, 1($5)
lw $4, 1($5)
lb $4, -1($5)
lbu $4, -1($5)
lh $4, -1($5)
lhu $4, -1($5)
lw $4, -1($5)
lb $4, 0x7FFF($5)
lbu $4, 0x7FFF($5)
lh $4, 0x7FFF($5)
lhu $4, 0x7FFF($5)
lw $4, 0x7FFF($5)
lb $4, -0x8000($5)
lbu $4, -0x8000($5)
lh $4, -0x8000($5)
lhu $4, -0x8000($5)
lw $4, -0x8000($5)
sb $4, ($5)
sh $4, ($5)
sw $4, ($5)
sb $4, 1($5)
sh $4, 1($5)
sw $4, 1($5)
sb $4, -1($5)
sh $4, -1($5)
sw $4, -1($5)
sb $4, 0x7FFF($5)
sh $4, 0x7FFF($5)
sw $4, 0x7FFF($5)
sb $4, -0x8000($5)
sh $4, -0x8000($5)
sw $4, -0x8000($5)
# MIPS32r2/PSP instructions
ext $2, $5, 20, 4
ext $15, $20, 3, 9
ins $2, $5, 20, 4
ins $15, $20, 3, 9
seb $7, $9
seh $7, $9
# PSP specific stuff
# max $4, $28, $15
# min $4, $28, $15
# movz $4, $5, $6
# movn $4, $5, $6

121
tests/mipsgen.c Normal file
View File

@ -0,0 +1,121 @@
#define u32 uint32_t
#define u8 uint8_t
#include <stdio.h>
#include <stdint.h>
#include "mips_codegen.h"
int main() {
u32 buffer[1024];
u8 *translation_ptr = (u8*)&buffer[0];
mips_emit_nop();
mips_emit_nop();
mips_emit_addu(mips_reg_a0, mips_reg_a1, mips_reg_a2);
mips_emit_addu(mips_reg_sp, mips_reg_ra, mips_reg_s4);
mips_emit_subu(mips_reg_a0, mips_reg_a1, mips_reg_a2);
mips_emit_subu(mips_reg_sp, mips_reg_ra, mips_reg_s4);
mips_emit_xor(mips_reg_a0, mips_reg_a1, mips_reg_a2);
mips_emit_xor(mips_reg_sp, mips_reg_ra, mips_reg_s4);
mips_emit_and(mips_reg_a0, mips_reg_a1, mips_reg_a2);
mips_emit_and(mips_reg_sp, mips_reg_ra, mips_reg_s4);
mips_emit_or(mips_reg_a0, mips_reg_a1, mips_reg_a2);
mips_emit_or(mips_reg_sp, mips_reg_ra, mips_reg_s4);
mips_emit_nor(mips_reg_a0, mips_reg_a1, mips_reg_a2);
mips_emit_nor(mips_reg_sp, mips_reg_ra, mips_reg_s4);
mips_emit_slt(mips_reg_a0, mips_reg_a1, mips_reg_a2);
mips_emit_slt(mips_reg_sp, mips_reg_ra, mips_reg_s4);
mips_emit_sltu(mips_reg_a0, mips_reg_a1, mips_reg_a2);
mips_emit_sltu(mips_reg_sp, mips_reg_ra, mips_reg_s4);
mips_emit_sllv(mips_reg_a0, mips_reg_a1, mips_reg_a2);
mips_emit_sllv(mips_reg_sp, mips_reg_ra, mips_reg_s4);
mips_emit_srlv(mips_reg_a0, mips_reg_a1, mips_reg_a2);
mips_emit_srlv(mips_reg_sp, mips_reg_ra, mips_reg_s4);
mips_emit_srav(mips_reg_a0, mips_reg_a1, mips_reg_a2);
mips_emit_srav(mips_reg_sp, mips_reg_ra, mips_reg_s4);
mips_emit_rotrv(mips_reg_a0, mips_reg_a1, mips_reg_a2);
mips_emit_rotrv(mips_reg_sp, mips_reg_ra, mips_reg_s4);
for (unsigned i = 0; i < 4; i++) {
mips_emit_sll(mips_reg_a0, mips_reg_a1, (i & 1) + (i >> 1) * 30);
mips_emit_srl(mips_reg_a0, mips_reg_a1, (i & 1) + (i >> 1) * 30);
mips_emit_sra(mips_reg_a0, mips_reg_a1, (i & 1) + (i >> 1) * 30);
mips_emit_rotr(mips_reg_a0, mips_reg_a1, (i & 1) + (i >> 1) * 30);
}
mips_emit_lui(mips_reg_a0, 0xFFFF);
mips_emit_lui(mips_reg_a0, 0x8000);
mips_emit_lui(mips_reg_a0, 0);
mips_emit_lui(mips_reg_a0, 1);
const int imm[] = {-1, 0, 1, 0x8000, 0x7FFF};
for (unsigned i = 0; i < 5; i++) {
mips_emit_addiu(mips_reg_a0, mips_reg_s6, imm[i]);
mips_emit_xori(mips_reg_a0, mips_reg_s6, imm[i]);
mips_emit_ori(mips_reg_a0, mips_reg_s6, imm[i]);
mips_emit_andi(mips_reg_a0, mips_reg_s6, imm[i]);
mips_emit_slti(mips_reg_a0, mips_reg_s6, imm[i]);
mips_emit_sltiu(mips_reg_a0, mips_reg_s6, imm[i]);
}
mips_emit_mflo(mips_reg_a3);
mips_emit_mflo(mips_reg_fp);
mips_emit_mfhi(mips_reg_a3);
mips_emit_mfhi(mips_reg_fp);
mips_emit_mtlo(mips_reg_a3);
mips_emit_mtlo(mips_reg_fp);
mips_emit_mthi(mips_reg_a3);
mips_emit_mthi(mips_reg_fp);
mips_emit_mult(mips_reg_a2, mips_reg_a3);
mips_emit_mult(mips_reg_s2, mips_reg_s4);
mips_emit_multu(mips_reg_a2, mips_reg_a3);
mips_emit_multu(mips_reg_s2, mips_reg_s4);
mips_emit_div(mips_reg_a2, mips_reg_a3);
mips_emit_div(mips_reg_s2, mips_reg_s4);
mips_emit_divu(mips_reg_a2, mips_reg_a3);
mips_emit_divu(mips_reg_s2, mips_reg_s4);
mips_emit_jr(mips_reg_a1);
mips_emit_jr(mips_reg_ra);
mips_emit_jalr(mips_reg_a1);
mips_emit_jalr(mips_reg_s4);
mips_emit_bltzal(mips_reg_a0, 5);
mips_emit_bltzal(mips_reg_s4, 4);
mips_emit_bgezal(mips_reg_a0, 3);
mips_emit_bgezal(mips_reg_s4, 2);
mips_emit_bltz(mips_reg_a0, 1);
mips_emit_bltz(mips_reg_s4, 0);
const int off[] = {0, 1, -1, 0x7FFF, -0x8000};
for (unsigned i = 0; i < 5; i++) {
mips_emit_lb(mips_reg_a0, mips_reg_a1, off[i]);
mips_emit_lbu(mips_reg_a0, mips_reg_a1, off[i]);
mips_emit_lh(mips_reg_a0, mips_reg_a1, off[i]);
mips_emit_lhu(mips_reg_a0, mips_reg_a1, off[i]);
mips_emit_lw(mips_reg_a0, mips_reg_a1, off[i]);
}
for (unsigned i = 0; i < 5; i++) {
mips_emit_sb(mips_reg_a0, mips_reg_a1, off[i]);
mips_emit_sh(mips_reg_a0, mips_reg_a1, off[i]);
mips_emit_sw(mips_reg_a0, mips_reg_a1, off[i]);
}
// MIPS32r2/PSP instructions
mips_emit_ext(mips_reg_v0, mips_reg_a1, 20, 4);
mips_emit_ext(mips_reg_t7, mips_reg_s4, 3, 9);
mips_emit_ins(mips_reg_v0, mips_reg_a1, 20, 4);
mips_emit_ins(mips_reg_t7, mips_reg_s4, 3, 9);
mips_emit_seb(mips_reg_a3, mips_reg_t1);
mips_emit_seh(mips_reg_a3, mips_reg_t1);
fwrite(buffer, 1, translation_ptr-(u8*)buffer, stdout);
}