initial Caanoo port
[gpsp.git] / disasm.c
1 /* gameplaySP
2  *
3  * Copyright (C) 2006 Exophase <exophase@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19
20
21 #define arm_decode_data_proc_reg()                                            \
22   u32 rn = (opcode >> 16) & 0x0F;                                             \
23   u32 rd = (opcode >> 12) & 0x0F;                                             \
24   u32 rm = opcode & 0x0F                                                      \
25
26 #define arm_decode_data_proc_imm()                                            \
27   u32 rn = (opcode >> 16) & 0x0F;                                             \
28   u32 rd = (opcode >> 12) & 0x0F;                                             \
29   u32 imm;                                                                    \
30   ror(imm, opcode & 0xFF, ((opcode >> 8) & 0x0F) * 2)                         \
31
32 #define arm_decode_psr_reg()                                                  \
33   u32 psr_field = (opcode >> 16) & 0x0F;                                      \
34   u32 rd = (opcode >> 12) & 0x0F;                                             \
35   u32 rm = opcode & 0x0F                                                      \
36
37 #define arm_decode_psr_imm()                                                  \
38   u32 psr_field = (opcode >> 16) & 0x0F;                                      \
39   u32 rd = (opcode >> 12) & 0x0F;                                             \
40   u32 imm;                                                                    \
41   ror(imm, opcode & 0xFF, ((opcode >> 8) & 0x0F) * 2)                         \
42
43 #define arm_decode_branchx()                                                  \
44   u32 rn = opcode & 0x0F                                                      \
45
46 #define arm_decode_multiply()                                                 \
47   u32 rd = (opcode >> 16) & 0x0F;                                             \
48   u32 rn = (opcode >> 12) & 0x0F;                                             \
49   u32 rs = (opcode >> 8) & 0x0F;                                              \
50   u32 rm = opcode & 0x0F                                                      \
51
52 #define arm_decode_multiply_long()                                            \
53   u32 rdhi = (opcode >> 16) & 0x0F;                                           \
54   u32 rdlo = (opcode >> 12) & 0x0F;                                           \
55   u32 rn = (opcode >> 8) & 0x0F;                                              \
56   u32 rm = opcode & 0x0F                                                      \
57
58 #define arm_decode_swap()                                                     \
59   u32 rn = (opcode >> 16) & 0x0F;                                             \
60   u32 rd = (opcode >> 12) & 0x0F;                                             \
61   u32 rm = opcode & 0x0F                                                      \
62
63 #define arm_decode_half_trans_r()                                             \
64   u32 rn = (opcode >> 16) & 0x0F;                                             \
65   u32 rd = (opcode >> 12) & 0x0F;                                             \
66   u32 rm = opcode & 0x0F                                                      \
67
68 #define arm_decode_half_trans_of()                                            \
69   u32 rn = (opcode >> 16) & 0x0F;                                             \
70   u32 rd = (opcode >> 12) & 0x0F;                                             \
71   u32 offset = ((opcode >> 4) & 0xF0) | (opcode & 0x0F)                       \
72
73 #define arm_decode_data_trans_imm()                                           \
74   u32 rn = (opcode >> 16) & 0x0F;                                             \
75   u32 rd = (opcode >> 12) & 0x0F;                                             \
76   u32 offset = opcode & 0x0FFF                                                \
77
78 #define arm_decode_data_trans_reg()                                           \
79   u32 rn = (opcode >> 16) & 0x0F;                                             \
80   u32 rd = (opcode >> 12) & 0x0F;                                             \
81   u32 rm = opcode & 0x0F                                                      \
82
83 #define arm_decode_block_trans()                                              \
84   u32 rn = (opcode >> 16) & 0x0F;                                             \
85   u32 reg_list = opcode & 0xFFFF                                              \
86
87 #define arm_decode_branch()                                                   \
88   s32 offset = ((s32)(opcode & 0xFFFFFF) << 8) >> 6                           \
89
90 #define thumb_decode_shift()                                                  \
91   u32 imm = (opcode >> 6) & 0x1F;                                             \
92   u32 rs = (opcode >> 3) & 0x07;                                              \
93   u32 rd = opcode & 0x07                                                      \
94
95 #define thumb_decode_add_sub()                                                \
96   u32 rn = (opcode >> 6) & 0x07;                                              \
97   u32 rs = (opcode >> 3) & 0x07;                                              \
98   u32 rd = opcode & 0x07                                                      \
99
100 #define thumb_decode_add_sub_imm()                                            \
101   u32 imm = (opcode >> 6) & 0x07;                                             \
102   u32 rs = (opcode >> 3) & 0x07;                                              \
103   u32 rd = opcode & 0x07                                                      \
104
105 #define thumb_decode_imm()                                                    \
106   u32 imm = opcode & 0xFF                                                     \
107
108 #define thumb_decode_alu_op()                                                 \
109   u32 rs = (opcode >> 3) & 0x07;                                              \
110   u32 rd = opcode & 0x07                                                      \
111
112 #define thumb_decode_hireg_op()                                               \
113   u32 rs = (opcode >> 3) & 0x0F;                                              \
114   u32 rd = ((opcode >> 4) & 0x08) | (opcode & 0x07)                           \
115
116 #define thumb_decode_mem_reg()                                                \
117   u32 ro = (opcode >> 6) & 0x07;                                              \
118   u32 rb = (opcode >> 3) & 0x07;                                              \
119   u32 rd = opcode & 0x07                                                      \
120
121 #define thumb_decode_mem_imm()                                                \
122   u32 imm = (opcode >> 6) & 0x1F;                                             \
123   u32 rb = (opcode >> 3) & 0x07;                                              \
124   u32 rd = opcode & 0x07                                                      \
125
126 #define thumb_decode_add_sp()                                                 \
127   u32 imm = opcode & 0x7F                                                     \
128
129 #define thumb_decode_rlist()                                                  \
130   u32 reg_list = opcode & 0xFF                                                \
131
132 #define thumb_decode_branch_cond()                                            \
133   s32 offset = (s8)(opcode & 0xFF)                                            \
134
135 #define thumb_decode_swi()                                                    \
136   u32 comment = opcode & 0xFF                                                 \
137
138 #define thumb_decode_branch()                                                 \
139   u32 offset = opcode & 0x07FF                                                \
140
141 const char *condition_table[] =
142 {
143   "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
144   "hi", "ls", "ge", "lt", "gt", "le", "al", "nv"
145 };
146
147 const char *data_proc_opcode_table[] =
148 {
149   "and", "eor", "sub", "rsb", "add", "adc", "sbc", "rsc",
150   "tst", "teq", "cmp", "cmn", "orr", "mov", "bic", "mvn"
151 };
152
153
154 u32 print_disasm_arm_instruction(u32 opcode)
155 {
156   u32 condition = opcode >> 28;
157
158   switch((opcode >> 25) & 0x07)
159   {
160     // Data processing reg, multiply, bx, memory transfer half/byte, swap,
161     // PSR reg
162     case 0x0:
163
164     // Data processing imm, PSR imm
165     case 0x1:
166
167     // Memory transfer imm
168     case 0x2:
169
170     // Memory transfer reg, undefined
171     case 0x3:
172
173     // Block memory transfer
174     case 0x4:
175
176     // Branch
177     case 0x5:
178
179     // Coprocessor
180     case 0x6:
181
182     // Coprocessor, SWI
183     case 0x7:
184   }