• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 #include <stdio.h>
29 #include <inttypes.h>
30 #include <string.h>
31 #include "../../../codeflinger/mips64_disassem.h"
32 
33 //typedef uint64_t db_addr_t;
34 //db_addr_t mips_disassem(db_addr_t loc, char *di_buffer, int alt_format);
35 
36 struct test_table_entry_t
37 {
38      uint32_t code;
39      const char *instr;
40 };
41 
42 static test_table_entry_t test_table [] =
43 {
44     { 0x00011020, "add\tv0,zero,at"     },
45     { 0x00832820, "add\ta1,a0,v1"       },
46     { 0x00c74020, "add\ta4,a2,a3"       },
47     { 0x012a5820, "add\ta7,a5,a6"       },
48     { 0x258dffff, "addiu\tt1,t0,-1"     },
49     { 0x25cf0004, "addiu\tt3,t2,4"      },
50     { 0x02119021, "addu\ts2,s0,s1"      },
51     { 0x0274a821, "addu\ts5,s3,s4"      },
52     { 0x02d7c024, "and\tt8,s6,s7"       },
53     { 0x333aff00, "andi\tk0,t9,0xff00"  },
54     { 0x3f7cffff, "aui\tgp,k1,-1"       },
55     { 0x3c1dffff, "lui\tsp,0xffff"      },
56     { 0x00e04051, "clo\ta4,a3"          },
57     { 0x01205050, "clz\ta6,a5"          },
58     { 0x016c682c, "dadd\tt1,a7,t0"      },
59     { 0x65cf0008, "daddiu\tt3,t2,8"     },
60     { 0x0211902d, "daddu\ts2,s0,s1"     },
61     { 0x7e741403, "dext\ts4,s3,16,3"    },
62     { 0x7eb6f801, "dextm\ts6,s5,0,64"   },
63     { 0x7ef87c02, "dextu\tt8,s7,48,16"  },
64     { 0x7f3a8207, "dins\tk0,t9,8,9"     },
65     { 0x7f7c0005, "dinsm\tgp,k1,0,33"   },
66     { 0x7fbe0806, "dinsu\ts8,sp,32,2"   },
67     { 0x03e1102e, "dsub\tv0,ra,at"      },
68     { 0x0064282f, "dsubu\ta1,v1,a0"     },
69     { 0x7cc77a00, "ext\ta3,a2,8,16"     },
70     { 0x7d09fc04, "ins\ta5,a4,16,16"    },
71     { 0x00200009, "jr\tat"              },
72     { 0x00201009, "jalr\tv0,at"         },
73     { 0x0020f809, "jalr\tat"            },
74     { 0x8082fff0, "lb\tv0,-16(a0)"      },
75     { 0x916c0008, "lbu\tt0,8(a7)"       },
76     { 0xdfa3ffe8, "ld\tv1,-24(sp)"      },
77     { 0x84850080, "lh\ta1,128(a0)"      },
78     { 0x94c7ff80, "lhu\ta3,-128(a2)"    },
79     { 0x8d09000c, "lw\ta5,12(a4)"       },
80     { 0x9d4bfff4, "lwu\ta7,-12(a6)"     },
81     { 0x00620898, "mul\tat,v1,v0"       },
82     { 0x006208d8, "muh\tat,v1,v0"       },
83     { 0x00620899, "mulu\tat,v1,v0"      },
84     { 0x006208d9, "muhu\tat,v1,v0"      },
85     { 0x00000000, "nop"                 },
86     { 0x02329827, "nor\ts3,s1,s2"       },
87     { 0x0295b025, "or\ts6,s4,s5"        },
88     { 0x36f0ff00, "ori\ts0,s7,0xff00"   },
89     { 0x7c03103b, "rdhwr\tv0,v1"        },
90     { 0x00242a02, "rotr\ta1,a0,8"       },
91     { 0x00c74046, "rotrv\ta4,a3,a2"     },
92     { 0xa12afff0, "sb\ta6,-16(a5)"      },
93     { 0xfd6c0100, "sd\tt0,256(a7)"      },
94     { 0x7c0d7420, "seb\tt2,t1"          },
95     { 0x7c0f8620, "seh\ts0,t3"          },
96     { 0x02329835, "seleqz\ts3,s1,s2"    },
97     { 0x0295b037, "selnez\ts6,s4,s5"    },
98     { 0xa6f84000, "sh\tt8,16384(s7)"    },
99     { 0x0019d100, "sll\tk0,t9,4"        },
100     { 0x037ce804, "sllv\tsp,gp,k1"      },
101     { 0x03df082a, "slt\tat,s8,ra"       },
102     { 0x28430007, "slti\tv1,v0,7"       },
103     { 0x2c850020, "sltiu\ta1,a0,32"     },
104     { 0x00c7402b, "sltu\ta4,a2,a3"      },
105     { 0x00095103, "sra\ta6,a5,4"        },
106     { 0x016c6807, "srav\tt1,t0,a7"      },
107     { 0x000e7a02, "srl\tt3,t2,8"        },
108     { 0x02119006, "srlv\ts2,s1,s0"      },
109     { 0x0274a822, "sub\ts5,s3,s4"       },
110     { 0x02d7c023, "subu\tt8,s6,s7"      },
111     { 0xaf3afffc, "sw\tk0,-4(t9)"       },
112     { 0x7c1be0a0, "wsbh\tgp,k1"         },
113     { 0x03bef826, "xor\tra,sp,s8"       },
114     { 0x3801ffff, "li\tat,0xffff"       },
115     { 0x3843ffff, "xori\tv1,v0,0xffff"  },
116 };
117 
118 struct test_branches_table_entry_t
119 {
120      uint32_t code;
121      const char *instr;
122      int16_t offset;
123 };
124 
125 static test_branches_table_entry_t test_branches_table [] = {
126     { 0x1000ffff, "b\t", static_cast<int16_t>(0xffff)         },
127     { 0x13df0008, "beq\ts8,ra,", 0x8                          },
128     { 0x042100ff, "bgez\tat,", 0xff                           },
129     { 0x1c40ff00, "bgtz\tv0,", static_cast<int16_t>(0xff00)   },
130     { 0x18605555, "blez\tv1,", 0x5555                         },
131     { 0x0480aaaa, "bltz\ta0,", static_cast<int16_t>(0xaaaa)   },
132     { 0x14a68888, "bne\ta1,a2,", static_cast<int16_t>(0x8888) },
133 };
134 
135 struct test_jump_table_entry_t
136 {
137      uint32_t code;
138      const char *instr;
139      int32_t offset;
140 };
141 
142 static test_jump_table_entry_t test_jump_table [] = {
143     { 0x0956ae66, "j\t", 0x156ae66          },
144     { 0x0d56ae66, "jal\t", 0x156ae66        },
145 };
146 
main()147 int main()
148 {
149     char instr[256];
150     uint32_t failed = 0;
151 
152     for(uint32_t i = 0; i < sizeof(test_table)/sizeof(test_table_entry_t); ++i)
153     {
154         test_table_entry_t *test;
155         test = &test_table[i];
156         mips_disassem(&test->code, instr, 0);
157         if(strcmp(instr, test->instr) != 0)
158         {
159             printf("Test Failed \n"
160                    "Code     : 0x%0x\n"
161                    "Expected : %s\n"
162                    "Actual   : %s\n", test->code, test->instr, instr);
163             failed++;
164         }
165     }
166     for(uint32_t i = 0; i < sizeof(test_branches_table)/sizeof(test_branches_table_entry_t); ++i)
167     {
168         test_branches_table_entry_t *test;
169         test = &test_branches_table[i];
170         mips_disassem(&test->code, instr, 0);
171         //printf("DBG code address: %lx\n", (uint64_t)(&test->code));
172         uint64_t loc = (uint64_t)test + 4 + (test->offset << 2);
173         //printf("DBG loc: %lx\n", loc);
174         char temp[256], address[16];
175         strcpy(temp, test->instr);
176         sprintf(address, "0x%lx", loc);
177         strcat(temp, address);
178         if(strcmp(instr, temp) != 0)
179         {
180             printf("Test Failed \n"
181                    "Code     : 0x%0x\n"
182                    "Expected : %s\n"
183                    "Actual   : %s\n", test->code, temp, instr);
184             failed++;
185         }
186     }
187     for(uint32_t i = 0; i < sizeof(test_jump_table)/sizeof(test_jump_table_entry_t); ++i)
188     {
189         test_jump_table_entry_t *test;
190         test = &test_jump_table[i];
191         mips_disassem(&test->code, instr, 0);
192         //printf("DBG code address: %lx\n", (uint64_t)(&test->code));
193         uint64_t loc = ((uint64_t)test & 0xfffffffff0000000) | (test->offset << 2);
194         //printf("DBG loc: %lx\n", loc);
195         char temp[256], address[16];
196         strcpy(temp, test->instr);
197         sprintf(address, "0x%08lx", loc);
198         strcat(temp, address);
199         if(strcmp(instr, temp) != 0)
200         {
201             printf("Test Failed \n"
202                    "Code     : 0x%0x\n"
203                    "Expected : '%s'\n"
204                    "Actual   : '%s'\n", test->code, temp, instr);
205             failed++;
206         }
207     }
208     if(failed == 0)
209     {
210         printf("All tests PASSED\n");
211         return 0;
212     }
213     else
214     {
215         printf("%d tests FAILED\n", failed);
216         return -1;
217     }
218 }
219