diff options
| author | IridiumXOR <oliveriandrea@gmail.com> | 2020-04-29 19:37:28 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-29 19:37:28 +0200 |
| commit | 9b92ca809557c5817250c7397bebb0f8dc9e8163 (patch) | |
| tree | eaa3426b4ce6c68199ee4c92ce222f6e95d8cd0b | |
| parent | 15e00a41277453ad65f08d04093ce1c7bcb952ea (diff) | |
| download | miasm-9b92ca809557c5817250c7397bebb0f8dc9e8163.tar.gz miasm-9b92ca809557c5817250c7397bebb0f8dc9e8163.zip | |
Add new MIPS opcodes (#1203)
* Add new MIPS opcodes * Add test for new opcodes and remove semantics for not implemented opcodes
| -rw-r--r-- | miasm/arch/mips32/arch.py | 13 | ||||
| -rw-r--r-- | miasm/arch/mips32/sem.py | 70 | ||||
| -rw-r--r-- | test/arch/mips32/arch.py | 17 |
3 files changed, 96 insertions, 4 deletions
diff --git a/miasm/arch/mips32/arch.py b/miasm/arch/mips32/arch.py index f1e52585..dcdfb707 100644 --- a/miasm/arch/mips32/arch.py +++ b/miasm/arch/mips32/arch.py @@ -47,8 +47,8 @@ class additional_info(object): self.except_on_instr = False br_0 = ['B', 'J', 'JR', 'BAL', 'JAL', 'JALR'] -br_1 = ['BGEZ', 'BLTZ', 'BGTZ', 'BLEZ', 'BC1T', 'BC1F'] -br_2 = ['BEQ', 'BEQL', 'BNE'] +br_1 = ['BGEZ', 'BLTZ', 'BGTZ', 'BGTZL', 'BLEZ', 'BLEZL', 'BC1T', 'BC1TL', 'BC1F', 'BC1FL'] +br_2 = ['BEQ', 'BEQL', 'BNE', 'BNEL'] class instruction_mips32(cpu.instruction): @@ -669,13 +669,18 @@ mips32op("mfhi", [cpu.bs('000000'), cpu.bs('0000000000'), rd, mips32op("b", [cpu.bs('000100'), cpu.bs('00000'), cpu.bs('00000'), soff], alias = True) mips32op("bne", [cpu.bs('000101'), rs, rt, soff]) +mips32op("bnel", [cpu.bs('010101'), rs, rt, soff]) + mips32op("beq", [cpu.bs('000100'), rs, rt, soff]) +mips32op("beql", [cpu.bs('010100'), rs, rt, soff]) mips32op("blez", [cpu.bs('000110'), rs, cpu.bs('00000'), soff]) +mips32op("blezl", [cpu.bs('010110'), rs, cpu.bs('00000'), soff]) mips32op("bcc", [cpu.bs('000001'), rs, bs_bcc, soff]) mips32op("bgtz", [cpu.bs('000111'), rs, cpu.bs('00000'), soff]) +mips32op("bgtzl", [cpu.bs('010111'), rs, cpu.bs('00000'), soff]) mips32op("bal", [cpu.bs('000001'), cpu.bs('00000'), cpu.bs('10001'), soff], alias = True) @@ -716,8 +721,12 @@ mips32op("c", [cpu.bs('010001'), bs_fmt, ft, fs, fcc, cpu.bs('0'), mips32op("bc1t", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('0'), cpu.bs('1'), soff]) +mips32op("bc1tl", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('1'), + cpu.bs('1'), soff]) mips32op("bc1f", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('0'), cpu.bs('0'), soff]) +mips32op("bc1fl", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('1'), + cpu.bs('0'), soff]) mips32op("swc1", [cpu.bs('111001'), base, ft, s16imm_noarg], [ft, base]) diff --git a/miasm/arch/mips32/sem.py b/miasm/arch/mips32/sem.py index 35fc5315..903be3be 100644 --- a/miasm/arch/mips32/sem.py +++ b/miasm/arch/mips32/sem.py @@ -67,6 +67,12 @@ def lbu(arg1, arg2): arg1 = mem8[arg2.ptr].zeroExtend(32) @sbuild.parse +def lh(arg1, arg2): + """A word is loaded into a register @arg1 from the + specified address @arg2.""" + arg1 = mem16[arg2.ptr].signExtend(32) + +@sbuild.parse def lhu(arg1, arg2): """A word is loaded (unsigned extended) into a register @arg1 from the specified address @arg2.""" @@ -85,6 +91,13 @@ def beq(arg1, arg2, arg3): ir.IRDst = dst @sbuild.parse +def beql(arg1, arg2, arg3): + "Branches on @arg3 if the quantities of two registers @arg1, @arg2 are eq" + dst = arg3 if ExprOp(m2_expr.TOK_EQUAL, arg1, arg2) else ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) + PC = dst + ir.IRDst = dst + +@sbuild.parse def bgez(arg1, arg2): """Branches on @arg2 if the quantities of register @arg1 is greater than or equal to zero""" @@ -93,6 +106,14 @@ def bgez(arg1, arg2): ir.IRDst = dst @sbuild.parse +def bgezl(arg1, arg2): + """Branches on @arg2 if the quantities of register @arg1 is greater than or + equal to zero""" + dst = ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if ExprOp(m2_expr.TOK_INF_SIGNED, arg1, ExprInt(0, arg1.size)) else arg2 + PC = dst + ir.IRDst = dst + +@sbuild.parse def bne(arg1, arg2, arg3): """Branches on @arg3 if the quantities of two registers @arg1, @arg2 are NOT equal""" @@ -101,6 +122,14 @@ def bne(arg1, arg2, arg3): ir.IRDst = dst @sbuild.parse +def bnel(arg1, arg2, arg3): + """Branches on @arg3 if the quantities of two registers @arg1, @arg2 are NOT + equal""" + dst = ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if ExprOp(m2_expr.TOK_EQUAL, arg1, arg2) else arg3 + PC = dst + ir.IRDst = dst + +@sbuild.parse def lui(arg1, arg2): """The immediate value @arg2 is shifted left 16 bits and stored in the register @arg1. The lower 16 bits are zeroes.""" @@ -248,6 +277,13 @@ def bltz(arg1, arg2): ir.IRDst = dst_o @sbuild.parse +def bltzl(arg1, arg2): + """Branches on @arg2 if the register @arg1 is less than zero""" + dst_o = arg2 if ExprOp(m2_expr.TOK_INF_SIGNED, arg1, ExprInt(0, arg1.size)) else ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) + PC = dst_o + ir.IRDst = dst_o + +@sbuild.parse def blez(arg1, arg2): """Branches on @arg2 if the register @arg1 is less than or equal to zero""" cond = ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, ExprInt(0, arg1.size)) @@ -256,6 +292,14 @@ def blez(arg1, arg2): ir.IRDst = dst_o @sbuild.parse +def blezl(arg1, arg2): + """Branches on @arg2 if the register @arg1 is less than or equal to zero""" + cond = ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, ExprInt(0, arg1.size)) + dst_o = arg2 if cond else ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) + PC = dst_o + ir.IRDst = dst_o + +@sbuild.parse def bgtz(arg1, arg2): """Branches on @arg2 if the register @arg1 is greater than zero""" cond = ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, ExprInt(0, arg1.size)) @@ -264,6 +308,14 @@ def bgtz(arg1, arg2): ir.IRDst = dst_o @sbuild.parse +def bgtzl(arg1, arg2): + """Branches on @arg2 if the register @arg1 is greater than zero""" + cond = ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, ExprInt(0, arg1.size)) + dst_o = ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if cond else arg2 + PC = dst_o + ir.IRDst = dst_o + +@sbuild.parse def wsbh(arg1, arg2): arg1 = ExprCompose(arg2[8:16], arg2[0:8], arg2[24:32], arg2[16:24]) @@ -364,12 +416,24 @@ def bc1t(arg1, arg2): ir.IRDst = dst_o @sbuild.parse +def bc1tl(arg1, arg2): + dst_o = arg2 if arg1 else ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) + PC = dst_o + ir.IRDst = dst_o + +@sbuild.parse def bc1f(arg1, arg2): dst_o = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if arg1 else arg2 PC = dst_o ir.IRDst = dst_o @sbuild.parse +def bc1fl(arg1, arg2): + dst_o = ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if arg1 else arg2 + PC = dst_o + ir.IRDst = dst_o + +@sbuild.parse def cvt_d_w(arg1, arg2): # TODO XXX arg1 = 'flt_d_w'(arg2) @@ -424,7 +488,6 @@ def ei(arg1): def ehb(arg1): "NOP" - def teq(ir, instr, arg1, arg2): e = [] @@ -473,7 +536,7 @@ mnemo_func.update({ 'subu': l_sub, 'xor': l_xor, 'xori': l_xor, - 'teq': teq, + 'teq': teq }) def get_mnemo_expr(ir, instr, *args): @@ -511,6 +574,9 @@ class ir_mips32l(IntermediateRepresentation): def get_next_break_loc_key(self, instr): return self.loc_db.get_or_create_offset_location(instr.offset + 8) + def get_next_delay_loc_key(self, instr): + return self.loc_db.get_or_create_offset_location(instr.offset + 16) + class ir_mips32b(ir_mips32l): def __init__(self, loc_db=None): self.addrsize = 32 diff --git a/test/arch/mips32/arch.py b/test/arch/mips32/arch.py index e5e8cff6..e14eda8a 100644 --- a/test/arch/mips32/arch.py +++ b/test/arch/mips32/arch.py @@ -214,6 +214,23 @@ reg_tests_mips32 = [ ("XXXXXXXX LDC1 F22, 0xFFFF9148(V0)", "D4569148"), + + ("XXXXXXXX BEQL S0, V0, 0x124", + "52020048"), + ("XXXXXXXX BGEZL T3, 0x24", + "05630008"), + ("XXXXXXXX BNEL A0, ZERO, 0x2C", + "5480000A"), + ("XXXXXXXX BLTZL S6, 0x5C", + "06C20016"), + ("XXXXXXXX BLEZL V1, 0x80", + "5860001F"), + ("XXXXXXXX BGTZL S4, 0x14", + "5E800004"), + ("XXXXXXXX BC1FL FCC0, 0x24", + "45020008"), + ("XXXXXXXX BC1TL FCC0, 0xB8", + "4503002D"), ] |