about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm/arch/mips32/arch.py13
-rw-r--r--miasm/arch/mips32/regs.py28
-rw-r--r--miasm/arch/mips32/sem.py70
-rw-r--r--miasm/arch/ppc/sem.py8
-rw-r--r--miasm/expression/expression.py2
-rw-r--r--miasm/jitter/arch/JitCore_mips32.h56
-rw-r--r--test/arch/mips32/arch.py17
7 files changed, 157 insertions, 37 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/regs.py b/miasm/arch/mips32/regs.py
index 1513e989..eee17caf 100644
--- a/miasm/arch/mips32/regs.py
+++ b/miasm/arch/mips32/regs.py
@@ -40,15 +40,43 @@ R_HI_init = ExprId('R_HI_init', 32)
 
 cpr0_str = ["CPR0_%d"%x for x in range(0x100)]
 cpr0_str[0] = "INDEX"
+cpr0_str[8] = "RANDOM"
 cpr0_str[16] = "ENTRYLO0"
 cpr0_str[24] = "ENTRYLO1"
+cpr0_str[32] = "CONTEXT"
+cpr0_str[33] = "CONTEXTCONFIG"
 cpr0_str[40] = "PAGEMASK"
+cpr0_str[41] = "PAGEGRAIN"
+cpr0_str[42] = "SEGCTL0"
+cpr0_str[43] = "SEGCTL1"
+cpr0_str[44] = "SEGCTL2"
+cpr0_str[45] = "PWBASE"
+cpr0_str[46] = "PWFIELD"
+cpr0_str[47] = "PWSIZE"
+cpr0_str[48] = "WIRED"
+cpr0_str[54] = "PWCTL"
+cpr0_str[64] = "BADVADDR"
+cpr0_str[65] = "BADINSTR"
+cpr0_str[66] = "BADINSTRP"
 cpr0_str[72] = "COUNT"
 cpr0_str[80] = "ENTRYHI"
 cpr0_str[104] = "CAUSE"
 cpr0_str[112] = "EPC"
+cpr0_str[120] = "PRID"
+cpr0_str[121] = "EBASE"
 cpr0_str[128] = "CONFIG"
+cpr0_str[129] = "CONFIG1"
+cpr0_str[130] = "CONFIG2"
+cpr0_str[131] = "CONFIG3"
+cpr0_str[132] = "CONFIG4"
+cpr0_str[133] = "CONFIG5"
 cpr0_str[152] = "WATCHHI"
+cpr0_str[250] = "KSCRATCH0"
+cpr0_str[251] = "KSCRATCH1"
+cpr0_str[252] = "KSCRATCH2"
+cpr0_str[253] = "KSCRATCH3"
+cpr0_str[254] = "KSCRATCH4"
+cpr0_str[255] = "KSCRATCH5"
 
 regs_cpr0_expr, regs_cpr0_init, regs_cpr0_info = gen_regs(cpr0_str, globals())
 
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/miasm/arch/ppc/sem.py b/miasm/arch/ppc/sem.py
index b2ca54b7..61330fe1 100644
--- a/miasm/arch/ppc/sem.py
+++ b/miasm/arch/ppc/sem.py
@@ -320,7 +320,7 @@ def mn_do_load(ir, instr, arg1, arg2, arg3=None):
 
 def mn_do_lmw(ir, instr, rd, src):
     ret = []
-    address = int(src)
+    address = src.ptr
     ri = int(rd.name[1:],10)
     i = 0
     while ri <= 31:
@@ -602,7 +602,7 @@ def mn_do_srw(ir, instr, ra, rs, rb):
 
 def mn_do_stmw(ir, instr, rs, dest):
     ret = []
-    address = int(dest)
+    address = dest.ptr
     ri = int(rs.name[1:],10)
     i = 0
     while ri <= 31:
@@ -675,8 +675,8 @@ def mn_do_store(ir, instr, arg1, arg2, arg3=None):
         ret.append(ExprAssign(ir.IRDst, loc_next))
         dont = flags + [ ExprAssign(CR0_EQ, ExprInt(0,1)),
                          ExprAssign(ir.IRDst, loc_next) ]
-        additional_ir = [ IRBlock(loc_do, [ AssignBlock(ret) ]),
-                          IRBlock(loc_dont, [ AssignBlock(dont) ]) ]
+        additional_ir = [ IRBlock(loc_do.loc_key, [ AssignBlock(ret) ]),
+                          IRBlock(loc_dont.loc_key, [ AssignBlock(dont) ]) ]
         ret = [ ExprAssign(reserve, ExprInt(0, 1)),
                 ExprAssign(ir.IRDst, ExprCond(reserve, loc_do, loc_dont)) ]
 
diff --git a/miasm/expression/expression.py b/miasm/expression/expression.py
index 18fcb77a..ef05a2b6 100644
--- a/miasm/expression/expression.py
+++ b/miasm/expression/expression.py
@@ -373,7 +373,7 @@ class ExprVisitorCallbackTopToBottom(ExprVisitorBase):
     """
     Rebuild expression by visiting sub-expressions
     Call @callback on each sub-expression
-    if @Ā¢allback return non None value, replace current node with this value
+    if @callback return non None value, replace current node with this value
     Else, continue visit of sub-expressions
     """
     def __init__(self, callback):
diff --git a/miasm/jitter/arch/JitCore_mips32.h b/miasm/jitter/arch/JitCore_mips32.h
index 74eb35ef..8478fb53 100644
--- a/miasm/jitter/arch/JitCore_mips32.h
+++ b/miasm/jitter/arch/JitCore_mips32.h
@@ -83,7 +83,7 @@ struct vm_cpu {
 	uint32_t CPR0_5;
 	uint32_t CPR0_6;
 	uint32_t CPR0_7;
-	uint32_t CPR0_8;
+	uint32_t RANDOM;
 	uint32_t CPR0_9;
 	uint32_t CPR0_10;
 	uint32_t CPR0_11;
@@ -107,8 +107,8 @@ struct vm_cpu {
 	uint32_t CPR0_29;
 	uint32_t CPR0_30;
 	uint32_t CPR0_31;
-	uint32_t CPR0_32;
-	uint32_t CPR0_33;
+	uint32_t CONTEXT;
+	uint32_t CONTEXTCONFIG;
 	uint32_t CPR0_34;
 	uint32_t CPR0_35;
 	uint32_t CPR0_36;
@@ -116,20 +116,20 @@ struct vm_cpu {
 	uint32_t CPR0_38;
 	uint32_t CPR0_39;
 	uint32_t PAGEMASK;
-	uint32_t CPR0_41;
-	uint32_t CPR0_42;
-	uint32_t CPR0_43;
-	uint32_t CPR0_44;
-	uint32_t CPR0_45;
-	uint32_t CPR0_46;
-	uint32_t CPR0_47;
-	uint32_t CPR0_48;
+	uint32_t PAGEGRAIN;
+	uint32_t SEGCTL0;
+	uint32_t SEGCTL1;
+	uint32_t SEGCTL2;
+	uint32_t PWBASE;
+	uint32_t PWFIELD;
+	uint32_t PWSIZE;
+	uint32_t WIRED;
 	uint32_t CPR0_49;
 	uint32_t CPR0_50;
 	uint32_t CPR0_51;
 	uint32_t CPR0_52;
 	uint32_t CPR0_53;
-	uint32_t CPR0_54;
+	uint32_t PWCTL;
 	uint32_t CPR0_55;
 	uint32_t CPR0_56;
 	uint32_t CPR0_57;
@@ -139,9 +139,9 @@ struct vm_cpu {
 	uint32_t CPR0_61;
 	uint32_t CPR0_62;
 	uint32_t CPR0_63;
-	uint32_t CPR0_64;
-	uint32_t CPR0_65;
-	uint32_t CPR0_66;
+	uint32_t BADVADDR;
+	uint32_t BADINSTR;
+	uint32_t BADINSTRP;
 	uint32_t CPR0_67;
 	uint32_t CPR0_68;
 	uint32_t CPR0_69;
@@ -195,8 +195,8 @@ struct vm_cpu {
 	uint32_t CPR0_117;
 	uint32_t CPR0_118;
 	uint32_t CPR0_119;
-	uint32_t CPR0_120;
-	uint32_t CPR0_121;
+	uint32_t PRID;
+	uint32_t EBASE;
 	uint32_t CPR0_122;
 	uint32_t CPR0_123;
 	uint32_t CPR0_124;
@@ -204,11 +204,11 @@ struct vm_cpu {
 	uint32_t CPR0_126;
 	uint32_t CPR0_127;
 	uint32_t CONFIG;
-	uint32_t CPR0_129;
-	uint32_t CPR0_130;
-	uint32_t CPR0_131;
-	uint32_t CPR0_132;
-	uint32_t CPR0_133;
+	uint32_t CONFIG1;
+	uint32_t CONFIG2;
+	uint32_t CONFIG3;
+	uint32_t CONFIG4;
+	uint32_t CONFIG5;
 	uint32_t CPR0_134;
 	uint32_t CPR0_135;
 	uint32_t CPR0_136;
@@ -325,12 +325,12 @@ struct vm_cpu {
 	uint32_t CPR0_247;
 	uint32_t CPR0_248;
 	uint32_t CPR0_249;
-	uint32_t CPR0_250;
-	uint32_t CPR0_251;
-	uint32_t CPR0_252;
-	uint32_t CPR0_253;
-	uint32_t CPR0_254;
-	uint32_t CPR0_255;
+	uint32_t KSCRATCH0;
+	uint32_t KSCRATCH1;
+	uint32_t KSCRATCH2;
+	uint32_t KSCRATCH3;
+	uint32_t KSCRATCH4;
+	uint32_t KSCRATCH5;
 };
 
 _MIASM_EXPORT void dump_gpregs(struct vm_cpu* vmcpu);
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"),
 ]