thumb.isa revision 6019
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007-2008 The Florida State University
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: 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 the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Stephen Hines
30
31////////////////////////////////////////////////////////////////////
32//
33// The actual ARM ISA decoder
34// --------------------------
35// The following instructions are specified in the ARM ISA
36// Specification. Decoding closely follows the style specified
37// in the ARM ISA specification document starting with Table B.1 or 3-1
38//
39//
40decode COND_CODE default Unknown::unknown() {
41    0xf: decode COND_CODE {
42        0x0: decode OPCODE_27_25 {
43            // Just a simple trick to allow us to specify our new uops here
44            0x0: PredImmOp::addi_uop({{ Raddr = Rn + rotated_imm; }},
45                                        'IsMicroop');
46            0x1: PredImmOp::subi_uop({{ Raddr = Rn - rotated_imm; }},
47                                        'IsMicroop');
48            0x2: ArmLoadMemory::ldr_uop({{ Rd = Mem; }},
49                                        {{ EA = Raddr + disp; }},
50                                           inst_flags = [IsMicroop]);
51            0x3: ArmStoreMemory::str_uop({{ Mem = Rd; }},
52                                         {{ EA = Raddr + disp; }},
53                                            inst_flags = [IsMicroop]);
54            0x4: PredImmOp::addi_rd_uop({{ Rd = Rn + rotated_imm; }},
55                                           'IsMicroop');
56            0x5: PredImmOp::subi_rd_uop({{ Rd = Rn - rotated_imm; }},
57                                           'IsMicroop');
58        }
59        0x1: decode OPCODE_27_25 {
60            0x0: PredIntOp::mvtd_uop({{ Fd.ud = ((uint64_t) Rhi << 32)|Rlo; }},
61                                        'IsMicroop');
62            0x1: PredIntOp::mvfd_uop({{ Rhi = (Fd.ud >> 32) & 0xffffffff;
63                                        Rlo = Fd.ud & 0xffffffff; }},
64                                        'IsMicroop');
65            0x2: ArmLoadMemory::ldhi_uop({{ Rhi = Mem; }},
66                                         {{ EA = Rn + disp; }},
67                                            inst_flags = [IsMicroop]);
68            0x3: ArmLoadMemory::ldlo_uop({{ Rlo = Mem; }},
69                                         {{ EA = Rn + disp; }},
70                                            inst_flags = [IsMicroop]);
71            0x4: ArmStoreMemory::sthi_uop({{ Mem = Rhi; }},
72                                          {{ EA = Rn + disp; }},
73                                             inst_flags = [IsMicroop]);
74            0x5: ArmStoreMemory::stlo_uop({{ Mem = Rlo; }},
75                                          {{ EA = Rn + disp; }},
76                                             inst_flags = [IsMicroop]);
77        }
78        default: Unknown::unknown(); // TODO: Ignore other NV space for now
79    }
80    format BasicOp{
81    default: decode OPCODE_27_25 {
82        0x0: decode OPCODE_4 {
83            0: decode S_FIELD {
84                0: decode OPCODE_24_21 {
85                    format PredIntOp {
86                    0x0: and({{ Rd = Rn & Rm_Imm; }});
87                    0x1: eor({{ Rd = Rn ^ Rm_Imm; }});
88                    0x2: sub({{ Rd = Rn - Rm_Imm; }});
89                    0x3: rsb({{ Rd = Rm_Imm - Rn; }});
90                    0x4: add({{ Rd = Rn + Rm_Imm; }});
91                    0x5: adc({{ Rd = Rn + Rm_Imm + Cpsr<29:>; }});
92                    0x6: sbc({{ Rd = Rn - Rm_Imm + Cpsr<29:> - 1; }});
93                    0x7: rsc({{ Rd = Rm_Imm - Rn + Cpsr<29:> - 1; }});
94                    //0x8:mrs_cpsr -- TODO
95                    //0x9:msr_cpsr -- TODO
96                    //0xa:mrs_spsr -- TODO
97                    //0xb:msr_spsr -- TODO
98                    0xc: orr({{ Rd = Rn | Rm_Imm; }});
99                    0xd: mov({{ Rd = Rm_Imm; }});
100                    0xe: bic({{ Rd = Rn & ~Rm_Imm; }});
101                    0xf: mvn({{ Rd = ~Rm_Imm; }});
102                    }
103                }
104                1: decode OPCODE_24_21 {
105                    format PredIntOpCc {
106                    0x0: ands({{
107                        uint32_t resTemp;
108                        Rd = resTemp = Rn & Rm_Imm;
109                        }},
110                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
111                        {{ Cpsr<28:> }});
112                    0x1: eors({{
113                        uint32_t resTemp;
114                        Rd = resTemp = Rn ^ Rm_Imm;
115                        }},
116                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
117                        {{ Cpsr<28:> }});
118                    0x2: subs({{
119                        uint32_t resTemp,
120                            val2 = Rm_Imm;
121                        Rd = resTemp = Rn - val2;
122                        }},
123                        {{ arm_sub_carry(resTemp, Rn, val2) }},
124                        {{ arm_sub_overflow(resTemp, Rn, val2) }});
125                    0x3: rsbs({{
126                        uint32_t resTemp,
127                            val2 = Rm_Imm;
128                        Rd = resTemp = val2 - Rn;
129                        }},
130                        {{ arm_sub_carry(resTemp, val2, Rn) }},
131                        {{ arm_sub_overflow(resTemp, val2, Rn) }});
132                    0x4: adds({{
133                        uint32_t resTemp,
134                            val2 = Rm_Imm;
135                        Rd = resTemp = Rn + val2;
136                        }},
137                        {{ arm_add_carry(resTemp, Rn, val2) }},
138                        {{ arm_add_overflow(resTemp, Rn, val2) }});
139                    0x5: adcs({{
140                        uint32_t resTemp,
141                            val2 = Rm_Imm;
142                        Rd = resTemp = Rn + val2 + Cpsr<29:>;
143                        }},
144                        {{ arm_add_carry(resTemp, Rn, val2) }},
145                        {{ arm_add_overflow(resTemp, Rn, val2) }});
146                    0x6: sbcs({{
147                        uint32_t resTemp,
148                            val2 = Rm_Imm;
149                        Rd = resTemp = Rn - val2 + Cpsr<29:> - 1;
150                        }},
151                        {{ arm_sub_carry(resTemp, Rn, val2) }},
152                        {{ arm_sub_overflow(resTemp, Rn, val2) }});
153                    0x7: rscs({{
154                        uint32_t resTemp,
155                            val2 = Rm_Imm;
156                        Rd = resTemp = val2 - Rn + Cpsr<29:> - 1;
157                        }},
158                        {{ arm_sub_carry(resTemp, val2, Rn) }},
159                        {{ arm_sub_overflow(resTemp, val2, Rn) }});
160                    0x8: tst({{
161                        uint32_t resTemp;
162                        resTemp = Rn & Rm_Imm;
163                        }},
164                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
165                        {{ Cpsr<28:> }});
166                    0x9: teq({{
167                        uint32_t resTemp;
168                        resTemp = Rn ^ Rm_Imm;
169                        }},
170                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
171                        {{ Cpsr<28:> }});
172                    0xa: cmp({{
173                        uint32_t resTemp,
174                            val2 = Rm_Imm;
175                        resTemp = Rn - val2;
176                        }},
177                        {{ arm_sub_carry(resTemp, Rn, val2) }},
178                        {{ arm_sub_overflow(resTemp, Rn, val2) }});
179                    0xb: cmn({{
180                        uint32_t resTemp,
181                            val2 = Rm_Imm;
182                        resTemp = Rn + val2;
183                        }},
184                        {{ arm_add_carry(resTemp, Rn, val2) }},
185                        {{ arm_add_overflow(resTemp, Rn, val2) }});
186                    0xc: orrs({{
187                        uint32_t resTemp,
188                            val2 = Rm_Imm;
189                        Rd = resTemp = Rn | val2;
190                        }},
191                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
192                        {{ Cpsr<28:> }});
193                    0xd: movs({{
194                        uint32_t resTemp;
195                        Rd = resTemp = Rm_Imm;
196                        }},
197                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
198                        {{ Cpsr<28:> }});
199                    0xe: bics({{
200                        uint32_t resTemp;
201                        Rd = resTemp = Rn & ~Rm_Imm;
202                        }},
203                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
204                        {{ Cpsr<28:> }});
205                    0xf: mvns({{
206                        uint32_t resTemp;
207                        Rd = resTemp = ~Rm_Imm;
208                        }},
209                        {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
210                        {{ Cpsr<28:> }});
211                    }
212                }
213            }
214            1: decode OPCODE_7 {
215                0: decode S_FIELD {
216                    0: decode OPCODE_24_21 {
217                        format PredIntOp {
218                        0x0: and_rs({{ Rd = Rn & Rm_Rs; }});
219                        0x1: eor_rs({{ Rd = Rn ^ Rm_Rs; }});
220                        0x2: sub_rs({{ Rd = Rn - Rm_Rs; }});
221                        0x3: rsb_rs({{ Rd = Rm_Rs - Rn; }});
222                        0x4: add_rs({{ Rd = Rn + Rm_Rs; }});
223                        0x5: adc_rs({{ Rd = Rn + Rm_Rs + Cpsr<29:>; }});
224                        0x6: sbc_rs({{ Rd = Rn - Rm_Rs + Cpsr<29:> - 1; }});
225                        0x7: rsc_rs({{ Rd = Rm_Rs - Rn + Cpsr<29:> - 1; }});
226                        0xc: orr_rs({{ Rd = Rn | Rm_Rs; }});
227                        0xd: mov_rs({{ Rd = Rm_Rs; }});
228                        0xe: bic_rs({{ Rd = Rn & ~Rm_Rs; }});
229                        0xf: mvn_rs({{ Rd = ~Rm_Rs; }});
230                        default: decode OPCODE_7_4 {
231                            0x1: decode OPCODE_24_21 {
232                                0x9: BranchExchange::bx({{ }});
233                                0xb: PredOp::clz({{
234                                    if (Rm == 0)
235                                        Rd = 32;
236                                    else
237                                    {
238                                        int i;
239                                        for (i = 0; i < 32; i++)
240                                        {
241                                            if (Rm & (1<<(31-i)))
242                                            break;
243                                        }
244                                        Rd = i;
245                                    }
246                                }});
247                            }
248                            0x3: decode OPCODE_24_21 {
249                                0x9: BranchExchange::blx({{ LR = NPC; }});
250                            }
251                        }
252                        }
253                    }
254                    1: decode OPCODE_24_21 {
255                        format PredIntOpCc {
256                        0x0: ands_rs({{
257                            uint32_t resTemp;
258                            Rd = resTemp = Rn & Rm_Rs;
259                            }},
260                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
261                            {{ Cpsr<28:> }});
262                        0x1: eors_rs({{
263                            uint32_t resTemp;
264                            Rd = resTemp = Rn ^ Rm_Rs;
265                            }},
266                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
267                            {{ Cpsr<28:> }});
268                        0x2: subs_rs({{
269                            uint32_t resTemp,
270                                val2 = Rm_Rs;
271                            Rd = resTemp = Rn - val2;
272                            }},
273                            {{ arm_sub_carry(resTemp, Rn, val2) }},
274                            {{ arm_sub_overflow(resTemp, Rn, val2) }});
275                        0x3: rsbs_rs({{
276                            uint32_t resTemp,
277                                val2 = Rm_Rs;
278                            Rd = resTemp = val2 - Rn;
279                            }},
280                            {{ arm_sub_carry(resTemp, val2, Rn) }},
281                            {{ arm_sub_overflow(resTemp, val2, Rn) }});
282                        0x4: adds_rs({{
283                            uint32_t resTemp,
284                                val2 = Rm_Rs;
285                            Rd = resTemp = Rn + val2;
286                            }},
287                            {{ arm_add_carry(resTemp, Rn, val2) }},
288                            {{ arm_add_overflow(resTemp, Rn, val2) }});
289                        0x5: adcs_rs({{
290                            uint32_t resTemp,
291                                val2 = Rm_Rs;
292                            Rd = resTemp = Rn + val2 + Cpsr<29:>;
293                            }},
294                            {{ arm_add_carry(resTemp, Rn, val2) }},
295                            {{ arm_add_overflow(resTemp, Rn, val2) }});
296                        0x6: sbcs_rs({{
297                            uint32_t resTemp,
298                                val2 = Rm_Rs;
299                            Rd = resTemp = Rn - val2 + Cpsr<29:> - 1;
300                            }},
301                            {{ arm_sub_carry(resTemp, Rn, val2) }},
302                            {{ arm_sub_overflow(resTemp, Rn, val2) }});
303                        0x7: rscs_rs({{
304                            uint32_t resTemp,
305                                val2 = Rm_Rs;
306                            Rd = resTemp = val2 - Rn + Cpsr<29:> - 1;
307                            }},
308                            {{ arm_sub_carry(resTemp, val2, Rn) }},
309                            {{ arm_sub_overflow(resTemp, val2, Rn) }});
310                        0x8: tst_rs({{
311                            uint32_t resTemp;
312                            resTemp = Rn & Rm_Rs;
313                            }},
314                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
315                            {{ Cpsr<28:> }});
316                        0x9: teq_rs({{
317                            uint32_t resTemp;
318                            resTemp = Rn ^ Rm_Rs;
319                            }},
320                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
321                            {{ Cpsr<28:> }});
322                        0xa: cmp_rs({{
323                            uint32_t resTemp,
324                                val2 = Rm_Rs;
325                            resTemp = Rn - val2;
326                            }},
327                            {{ arm_sub_carry(resTemp, Rn, val2) }},
328                            {{ arm_sub_overflow(resTemp, Rn, val2) }});
329                        0xb: cmn_rs({{
330                            uint32_t resTemp,
331                                val2 = Rm_Rs;
332                            resTemp = Rn + val2;
333                            }},
334                            {{ arm_add_carry(resTemp, Rn, val2) }},
335                            {{ arm_add_overflow(resTemp, Rn, val2) }});
336                        0xc: orrs_rs({{
337                            uint32_t resTemp,
338                                val2 = Rm_Rs;
339                            Rd = resTemp = Rn | val2;
340                            }},
341                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
342                            {{ Cpsr<28:> }});
343                        0xd: movs_rs({{
344                            uint32_t resTemp;
345                            Rd = resTemp = Rm_Rs;
346                            }},
347                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
348                            {{ Cpsr<28:> }});
349                        0xe: bics_rs({{
350                            uint32_t resTemp;
351                            Rd = resTemp = Rn & ~Rm_Rs;
352                            }},
353                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
354                            {{ Cpsr<28:> }});
355                        0xf: mvns_rs({{
356                            uint32_t resTemp;
357                            Rd = resTemp = ~Rm_Rs;
358                            }},
359                            {{ shift_carry_rs(Rm, Rs, shift, Cpsr<29:>) }},
360                            {{ Cpsr<28:> }});
361                        }
362                    }
363                }
364                1: decode OPCODE_6_5 {
365                    0x0: decode OPCODE_24 {
366                        0: decode LUAS {
367                            format PredIntOp {
368                            0x0: mul({{ Rn = Rm * Rs; }});
369                            0x1: PredIntOpCc::muls({{
370                                uint32_t resTemp;
371                                Rn = resTemp = Rm * Rs;
372                                }},
373                                {{ Cpsr<29:> }},
374                                {{ Cpsr<28:> }});
375                            0x2: mla_a({{ Rn = Rm * Rs + Rd; }});
376                            0x8: umull_l({{
377                                uint64_t resTemp;
378                                resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
379                                Rd = (uint32_t)(resTemp & 0xffffffff);
380                                Rn = (uint32_t)(resTemp >> 32);
381                            }});
382                            0xa: umlal_lu({{
383                                uint64_t resTemp;
384                                resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
385                                resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
386                                Rd = (uint32_t)(resTemp & 0xffffffff);
387                                Rn = (uint32_t)(resTemp >> 32);
388                            }});
389                            0xc: smull_lu({{
390                                int64_t resTemp;
391                                resTemp = ((int64_t)Rm)*((int64_t)Rs);
392                                Rd = (int32_t)(resTemp & 0xffffffff);
393                                Rn = (int32_t)(resTemp >> 32);
394                            }});
395                            }
396                        }
397                    }
398                    0x1: decode PUIWL {
399                        0x04,0x0c: ArmStoreMemory::strh_i({{ Mem.uh = Rd.uh;
400                                                          Rn = Rn + hilo; }},
401                                                       {{ EA = Rn; }});
402                        0x05,0x0d: ArmLoadMemory::ldrh_il({{ Rd.uh = Mem.uh;
403                                                          Rn = Rn + hilo; }},
404                                                       {{ EA = Rn; }});
405                        0x10,0x18: ArmStoreMemory::strh_p({{ Mem.uh = Rd.uh; }},
406                                                        {{ EA = Rn + Rm; }});
407                        0x11,0x19: ArmLoadMemory::ldrh_pl({{ Rd.uh = Mem.uh; }},
408                                                        {{ EA = Rn + Rm; }});
409                        0x12,0x1a: ArmStoreMemory::strh_pw({{ Mem.uh = Rd.uh;
410                                                          Rn = Rn + Rm; }},
411                                                       {{ EA = Rn + Rm; }});
412                        0x13,0x1b: ArmLoadMemory::ldrh_pwl({{ Rd.uh = Mem.uh;
413                                                          Rn = Rn + Rm; }},
414                                                       {{ EA = Rn + Rm; }});
415                        0x14,0x1c: ArmStoreMemory::strh_pi({{ Mem.uh = Rd.uh; }},
416                                                        {{ EA = Rn + hilo; }});
417                        0x15,0x1d: ArmLoadMemory::ldrh_pil({{ Rd.uh = Mem.uh; }},
418                                                       {{ EA = Rn + hilo; }});
419                        0x16,0x1e: ArmStoreMemory::strh_piw({{ Mem.uh = Rd.uh;
420                                                           Rn = Rn + hilo; }},
421                                                        {{ EA = Rn + hilo; }});
422                        0x17,0x1f: ArmLoadMemory::ldrh_piwl({{ Rd.uh = Mem.uh;
423                                                           Rn = Rn + hilo; }},
424                                                        {{ EA = Rn + hilo; }});
425                    }
426                    0x2: decode PUIWL {
427                        format ArmLoadMemory {
428                            0x11,0x19: ldrsb_pl({{ Rd.sb = Mem.sb; }},
429                                                {{ EA = Rn + Rm; }});
430                            0x13,0x1b: ldrsb_pwl({{ Rd.sb = Mem.sb;
431                                                    Rn = Rn + Rm; }},
432                                                 {{ EA = Rn + Rm; }});
433                            0x15,0x1d: ldrsb_pil({{ Rd.sb = Mem.sb; }},
434                                                 {{ EA = Rn + hilo; }});
435                            0x17,0x1f: ldrsb_piwl({{ Rd.sb = Mem.sb;
436                                                     Rn = Rn + hilo; }},
437                                                  {{ EA = Rn + hilo; }});
438                        }
439                    }
440                    0x3: decode PUIWL {
441                        format ArmLoadMemory {
442                            0x11,0x19: ldrsh_pl({{ Rd.sh = Mem.sh; }},
443                                                {{ EA = Rn + Rm; }});
444                            0x13,0x1b: ldrsh_pwl({{ Rd.sh = Mem.sh;
445                                                    Rn = Rn + Rm; }},
446                                                 {{ EA = Rn + Rm; }});
447                            0x15,0x1d: ldrsh_pil({{ Rd.sh = Mem.sh; }},
448                                                 {{ EA = Rn + hilo; }});
449                            0x17,0x1f: ldrsh_piwl({{ Rd.sh = Mem.sh;
450                                                     Rn = Rn + hilo; }},
451                                                  {{ EA = Rn + hilo; }});
452                        }
453                    }
454                }
455            }
456        }
457        0x1: decode S_FIELD {
458            0: decode OPCODE_24_21 {
459                format PredImmOp {
460                    0x0: andi({{ Rd = Rn & rotated_imm; }});
461                    0x1: eori({{ Rd = Rn ^ rotated_imm; }});
462                    0x2: subi({{ Rd = Rn - rotated_imm; }});
463                    0x3: rsbi({{ Rd = rotated_imm - Rn; }});
464                    0x4: addi({{ Rd = Rn + rotated_imm; }});
465                    0x5: adci({{ Rd = Rn + rotated_imm + Cpsr<29:>; }});
466                    0x6: sbci({{ Rd = Rn - rotated_imm + Cpsr<29:> - 1; }});
467                    0x7: rsci({{ Rd = rotated_imm - Rn + Cpsr<29:> - 1; }});
468                    0xc: orri({{ Rd = Rn | rotated_imm; }});
469                    0xd: decode RN {
470                        0: movi({{ Rd = rotated_imm; }});
471                    }
472                    0xe: bici({{ Rd = Rn & ~rotated_imm; }});
473                    0xf: decode RN {
474                        0: mvni({{ Rd = ~rotated_imm; }});
475                    }
476                }
477            }
478            1: decode OPCODE_24_21 {
479                format PredImmOpCc {
480                    0x0: andsi({{
481                        uint32_t resTemp;
482                        Rd = resTemp = Rn & rotated_imm;
483                        }},
484                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
485                        {{ Cpsr<28:> }});
486                    0x1: eorsi({{
487                        uint32_t resTemp;
488                        Rd = resTemp = Rn ^ rotated_imm;
489                        }},
490                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
491                        {{ Cpsr<28:> }});
492                    0x2: subsi({{
493                        uint32_t resTemp;
494                        Rd = resTemp = Rn - rotated_imm;
495                        }},
496                        {{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
497                        {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
498                    0x3: rsbsi({{
499                        uint32_t resTemp;
500                        Rd = resTemp = rotated_imm - Rn;
501                        }},
502                        {{ arm_sub_carry(resTemp, rotated_imm, Rn) }},
503                        {{ arm_sub_overflow(resTemp, rotated_imm, Rn) }});
504                    0x4: addsi({{
505                        uint32_t resTemp;
506                        Rd = resTemp = Rn + rotated_imm;
507                        }},
508                        {{ arm_add_carry(resTemp, Rn, rotated_imm) }},
509                        {{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
510                    0x5: adcsi({{
511                        uint32_t resTemp;
512                        Rd = resTemp = Rn + rotated_imm + Cpsr<29:>;
513                        }},
514                        {{ arm_add_carry(resTemp, Rn, rotated_imm) }},
515                        {{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
516                    0x6: sbcsi({{
517                        uint32_t resTemp;
518                        Rd = resTemp = Rn -rotated_imm + Cpsr<29:> - 1;
519                        }},
520                        {{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
521                        {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
522                    0x7: rscsi({{
523                        uint32_t resTemp;
524                        Rd = resTemp = rotated_imm - Rn + Cpsr<29:> - 1;
525                        }},
526                        {{ arm_sub_carry(resTemp, rotated_imm, Rn) }},
527                        {{ arm_sub_overflow(resTemp, rotated_imm, Rn) }});
528                    0x8: tsti({{
529                        uint32_t resTemp;
530                        resTemp = Rn & rotated_imm;
531                        }},
532                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
533                        {{ Cpsr<28:> }});
534                    0x9: teqi({{
535                        uint32_t resTemp;
536                        resTemp = Rn ^ rotated_imm;
537                        }},
538                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
539                        {{ Cpsr<28:> }});
540                    0xa: cmpi({{
541                        uint32_t resTemp;
542                        resTemp = Rn - rotated_imm;
543                        }},
544                        {{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
545                        {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
546                    0xb: cmni({{
547                        uint32_t resTemp;
548                        resTemp = Rn + rotated_imm;
549                        }},
550                        {{ arm_add_carry(resTemp, Rn, rotated_imm) }},
551                        {{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
552                    0xc: orrsi({{
553                        uint32_t resTemp;
554                        Rd = resTemp = Rn | rotated_imm;
555                        }},
556                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
557                        {{ Cpsr<28:> }});
558                    0xd: movsi({{
559                        uint32_t resTemp;
560                        Rd = resTemp = rotated_imm;
561                        }},
562                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
563                        {{ Cpsr<28:> }});
564                    0xe: bicsi({{
565                        uint32_t resTemp;
566                        Rd = resTemp = Rn & ~rotated_imm;
567                        }},
568                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
569                        {{ Cpsr<28:> }});
570                    0xf: mvnsi({{
571                        uint32_t resTemp;
572                        Rd = resTemp = ~rotated_imm;
573                        }},
574                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
575                        {{ Cpsr<28:> }});
576                }
577            }
578        }
579        0x2: decode PUBWL {
580            // CAREFUL:
581            // Can always do EA + disp, since we negate disp using the UP flag
582            // Post-indexed variants
583            0x00,0x08: ArmStoreMemory::str_({{ Mem = Rd;
584                                               Rn = Rn + disp; }},
585                                            {{ EA = Rn; }});
586            0x01,0x09: ArmLoadMemory::ldr_l({{ Rd = Mem;
587                                               Rn = Rn + disp; }},
588                                            {{ EA = Rn; }});
589            0x04,0x0c: ArmStoreMemory::strb_b({{ Mem.ub = Rd.ub;
590                                                 Rn = Rn + disp; }},
591                                              {{ EA = Rn; }});
592            0x05,0x0d: ArmLoadMemory::ldrb_bl({{ Rd.ub = Mem.ub;
593                                                 Rn = Rn + disp; }},
594                                              {{ EA = Rn; }});
595            // Pre-indexed variants
596            0x10,0x18: ArmStoreMemory::str_p({{ Mem = Rd; }});
597            0x11,0x19: ArmLoadMemory::ldr_pl({{ Rd = Mem; }});
598            0x12,0x1a: ArmStoreMemory::str_pw({{ Mem = Rd;
599                                                 Rn = Rn + disp; }});
600            0x13,0x1b: ArmLoadMemory::ldr_pwl({{ Rd = Mem;
601                                                 Rn = Rn + disp; }});
602            0x14,0x1c: ArmStoreMemory::strb_pb({{ Mem.ub = Rd.ub; }});
603            0x15,0x1d: ArmLoadMemory::ldrb_pbl({{ Rd.ub = Mem.ub; }});
604            0x16,0x1e: ArmStoreMemory::strb_pbw({{ Mem.ub = Rd.ub;
605                                                   Rn = Rn + disp; }});
606            0x17,0x1f: ArmLoadMemory::ldrb_pbwl({{ Rd.ub = Mem.ub;
607                                                   Rn = Rn + disp; }});
608        }
609        0x3: decode OPCODE_4 {
610            0: decode PUBWL {
611                0x00,0x08: ArmStoreMemory::strr_({{
612                        Mem = Rd;
613                        Rn = Rn + Rm_Imm; }},
614                     {{ EA = Rn; }});
615                0x01,0x09: ArmLoadMemory::ldrr_l({{
616                        Rd = Mem;
617                        Rn = Rn + Rm_Imm; }},
618                     {{ EA = Rn; }});
619                0x04,0x0c: ArmStoreMemory::strr_b({{
620                        Mem.ub = Rd.ub;
621                        Rn = Rn + Rm_Imm; }},
622                     {{ EA = Rn; }});
623                0x05,0x0d: ArmLoadMemory::ldrr_bl({{
624                        Rd.ub = Mem.ub;
625                        Rn = Rn + Rm_Imm; }},
626                     {{ EA = Rn; }});
627                0x10,0x18: ArmStoreMemory::strr_p({{
628                        Mem = Rd; }},
629                     {{ EA = Rn + Rm_Imm; }});
630                0x11,0x19: ArmLoadMemory::ldrr_pl({{
631                        Rd = Mem; }},
632                     {{ EA = Rn + Rm_Imm; }});
633                0x12,0x1a: ArmStoreMemory::strr_pw({{
634                        Mem = Rd;
635                        Rn = Rn + Rm_Imm; }},
636                     {{ EA = Rn + Rm_Imm; }});
637                0x13,0x1b: ArmLoadMemory::ldrr_pwl({{
638                        Rd = Mem;
639                        Rn = Rn + Rm_Imm; }},
640                     {{ EA = Rn + Rm_Imm; }});
641                0x14,0x1c: ArmStoreMemory::strr_pb({{
642                        Mem.ub = Rd.ub; }},
643                     {{ EA = Rn + Rm_Imm; }});
644                0x15,0x1d: ArmLoadMemory::ldrr_pbl({{
645                        Rd.ub = Mem.ub; }},
646                     {{ EA = Rn + Rm_Imm; }});
647                0x16,0x1e: ArmStoreMemory::strr_pbw({{
648                        Mem.ub = Rd.ub;
649                        Rn = Rn + Rm_Imm; }},
650                     {{ EA = Rn + Rm_Imm; }});
651                0x17,0x1f: ArmLoadMemory::ldrr_pbwl({{
652                        Rd.ub = Mem.ub;
653                        Rn = Rn + Rm_Imm; }},
654                     {{ EA = Rn + Rm_Imm; }});
655            }
656        }
657        0x4: decode PUSWL {
658            // Right now we only handle cases when S (PSRUSER) is not set
659            default: ArmMacroStore::ldmstm({{ }});
660        }
661        0x5: decode OPCODE_24 {
662            // Branch (and Link) Instructions
663            0: Branch::b({{ }});
664            1: Branch::bl({{ LR = NPC; }});
665        }
666        0x6: decode CPNUM {
667            0x1: decode PUNWL {
668                0x02,0x0a: decode OPCODE_15 {
669                    0: ArmStoreMemory::stfs_({{ Mem.sf = Fd.sf;
670                                                Rn = Rn + disp8; }},
671                        {{ EA = Rn; }});
672                    1: ArmMacroFPAOp::stfd_({{ }});
673                }
674                0x03,0x0b: decode OPCODE_15 {
675                    0: ArmLoadMemory::ldfs_({{ Fd.sf = Mem.sf;
676                                               Rn = Rn + disp8; }},
677                        {{ EA = Rn; }});
678                    1: ArmMacroFPAOp::ldfd_({{ }});
679                }
680                0x06,0x0e: decode OPCODE_15 {
681                    0: ArmMacroFPAOp::stfe_nw({{ }});
682                }
683                0x07,0x0f: decode OPCODE_15 {
684                    0: ArmMacroFPAOp::ldfe_nw({{ }});
685                }
686                0x10,0x18: decode OPCODE_15 {
687                    0: ArmStoreMemory::stfs_p({{ Mem.sf = Fd.sf; }},
688                        {{ EA = Rn + disp8; }});
689                    1: ArmMacroFPAOp::stfd_p({{ }});
690                }
691                0x11,0x19: decode OPCODE_15 {
692                    0: ArmLoadMemory::ldfs_p({{ Fd.sf = Mem.sf; }},
693                        {{ EA = Rn + disp8; }});
694                    1: ArmMacroFPAOp::ldfd_p({{ }});
695                }
696                0x12,0x1a: decode OPCODE_15 {
697                    0: ArmStoreMemory::stfs_pw({{ Mem.sf = Fd.sf;
698                                                  Rn = Rn + disp8; }},
699                        {{ EA = Rn + disp8; }});
700                    1: ArmMacroFPAOp::stfd_pw({{ }});
701                }
702                0x13,0x1b: decode OPCODE_15 {
703                    0: ArmLoadMemory::ldfs_pw({{ Fd.sf = Mem.sf;
704                                                 Rn = Rn + disp8; }},
705                        {{ EA = Rn + disp8; }});
706                    1: ArmMacroFPAOp::ldfd_pw({{ }});
707                }
708                0x14,0x1c: decode OPCODE_15 {
709                    0: ArmMacroFPAOp::stfe_pn({{ }});
710                }
711                0x15,0x1d: decode OPCODE_15 {
712                    0: ArmMacroFPAOp::ldfe_pn({{ }});
713                }
714                0x16,0x1e: decode OPCODE_15 {
715                    0: ArmMacroFPAOp::stfe_pnw({{ }});
716                }
717                0x17,0x1f: decode OPCODE_15 {
718                    0: ArmMacroFPAOp::ldfe_pnw({{ }});
719                }
720            }
721            0x2: decode PUNWL {
722                // could really just decode as a single instruction
723                0x00,0x04,0x08,0x0c: ArmMacroFMOp::sfm_({{ }});
724                0x01,0x05,0x09,0x0d: ArmMacroFMOp::lfm_({{ }});
725                0x02,0x06,0x0a,0x0e: ArmMacroFMOp::sfm_w({{ }});
726                0x03,0x07,0x0b,0x0f: ArmMacroFMOp::lfm_w({{ }});
727                0x10,0x14,0x18,0x1c: ArmMacroFMOp::sfm_p({{ }});
728                0x11,0x15,0x19,0x1d: ArmMacroFMOp::lfm_p({{ }});
729                0x12,0x16,0x1a,0x1e: ArmMacroFMOp::sfm_pw({{ }});
730                0x13,0x17,0x1b,0x1f: ArmMacroFMOp::lfm_pw({{ }});
731            }
732        }
733        0x7: decode OPCODE_24 {
734            0: decode CPNUM {
735                // Coprocessor Instructions
736                0x1: decode OPCODE_4 {
737                    format FloatOp {
738                        // Basic FPA Instructions
739                        0: decode OPCODE_23_20 {
740                            0x0: decode OPCODE_15 {
741                                0: adf({{ Fd.sf = Fn.sf + Fm.sf; }});
742                                1: mvf({{ Fd.sf = Fm.sf; }});
743                            }
744                            0x1: decode OPCODE_15 {
745                                0: muf({{ Fd.sf = Fn.sf * Fm.sf; }});
746                                1: mnf({{ Fd.sf = -Fm.sf; }});
747                            }
748                            0x2: decode OPCODE_15 {
749                                0: suf({{ Fd.sf = Fn.sf - Fm.sf; }});
750                                1: abs({{ Fd.sf = fabs(Fm.sf); }});
751                            }
752                            0x3: decode OPCODE_15 {
753                                0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }});
754                                1: rnd({{ Fd.sf = rint(Fm.sf); }});
755                            }
756                            0x4: decode OPCODE_15 {
757                                0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }});
758                                1: sqt({{ Fd.sf = sqrt(Fm.sf); }});
759                            }
760                            0x5: decode OPCODE_15 {
761                                0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }});
762                                1: log({{ Fd.sf = log10(Fm.sf); }});
763                            }
764                            0x6: decode OPCODE_15 {
765                                0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }});
766                                1: lgn({{ Fd.sf = log(Fm.sf); }});
767                            }
768                            0x7: decode OPCODE_15 {
769                                0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }});
770                                1: exp({{ Fd.sf = exp(Fm.sf); }});
771                            }
772                            0x8: decode OPCODE_15 {
773                                0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }});
774                                1: sin({{ Fd.sf = sin(Fm.sf); }});
775                            }
776                            0x9: decode OPCODE_15 {
777                                0: fml({{ Fd.sf = Fn.sf * Fm.sf; }});
778                                1: cos({{ Fd.sf = cos(Fm.sf); }});
779                            }
780                            0xa: decode OPCODE_15 {
781                                0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }});
782                                1: tan({{ Fd.sf = tan(Fm.sf); }});
783                            }
784                            0xb: decode OPCODE_15 {
785                                0: frd({{ Fd.sf = Fm.sf / Fn.sf; }});
786                                1: asn({{ Fd.sf = asin(Fm.sf); }});
787                            }
788                            0xc: decode OPCODE_15 {
789                                0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }});
790                                1: acs({{ Fd.sf = acos(Fm.sf); }});
791                            }
792                            0xd: decode OPCODE_15 {
793                                1: atn({{ Fd.sf = atan(Fm.sf); }});
794                            }
795                            0xe: decode OPCODE_15 {
796                                // Unnormalised Round
797                                1: FailUnimpl::urd();
798                            }
799                            0xf: decode OPCODE_15 {
800                                // Normalise
801                                1: FailUnimpl::nrm();
802                            }
803                        }
804                        1: decode OPCODE_15_12 {
805                            0xf: decode OPCODE_23_21 {
806                                format FloatCmp {
807                                    0x4: cmf({{ Fn.df }}, {{ Fm.df }});
808                                    0x5: cnf({{ Fn.df }}, {{ -Fm.df }});
809                                    0x6: cmfe({{ Fn.df }}, {{ Fm.df}});
810                                    0x7: cnfe({{ Fn.df }}, {{ -Fm.df}});
811                                }
812                            }
813                            default: decode OPCODE_23_20 {
814                                0x0: decode OPCODE_7 {
815                                    0: flts({{ Fn.sf = (float) Rd.sw; }});
816                                    1: fltd({{ Fn.df = (double) Rd.sw; }});
817                                }
818                                0x1: decode OPCODE_7 {
819                                    0: fixs({{ Rd = (uint32_t) Fm.sf; }});
820                                    1: fixd({{ Rd = (uint32_t) Fm.df; }});
821                                }
822                                0x2: wfs({{ Fpsr = Rd; }});
823                                0x3: rfs({{ Rd = Fpsr; }});
824                                0x4: FailUnimpl::wfc();
825                                0x5: FailUnimpl::rfc();
826                            }
827                        }
828                    }
829                }
830            }
831            format PredOp {
832                // ARM System Call (SoftWare Interrupt)
833                1: swi({{ if (arm_predicate(xc->readMiscReg(ArmISA::CPSR),
834                              condCode))
835                          {
836                              //xc->syscall(R7);
837                              xc->syscall(IMMED_23_0);
838                          }
839                }});
840            }
841        }
842    }
843    }
844}
845
846