thumb.isa revision 6268
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 {
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 {
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    }
80default: decode ENCODING {
81format DataOp {
82    0x0: decode SEVEN_AND_FOUR {
83        1: decode MISC_OPCODE {
84            0x9: decode PREPOST {
85                0: decode OPCODE {
86                    0x0: mul({{ uint32_t resTemp;
87                                Rn = resTemp = Rm * Rs; }},
88                             {{ Cpsr<29:> }},
89                             {{ Cpsr<28:> }});
90                    0x1: mla({{ uint32_t resTemp;
91                                Rn = resTemp = Rm * Rs; }},
92                             {{ Cpsr<29:> }},
93                             {{ Cpsr<28:> }});
94                    0x2: WarnUnimpl::umall();
95                    0x4: umull({{
96                        uint64_t resTemp;
97                        resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
98                        Rd = (uint32_t)(resTemp & 0xffffffff);
99                        Rn = (uint32_t)(resTemp >> 32);
100                    }}, {{ 1 }}, {{ 1 }});
101                    0x5: WarnUnimpl::smlal();
102                    0x6: smull({{
103                        int64_t resTemp;
104                        resTemp = ((int64_t)Rm.sw)*((int64_t)Rs.sw);
105                        Rd = (int32_t)(resTemp & 0xffffffff);
106                        Rn = (int32_t)(resTemp >> 32);
107                    }}, {{ 1 }}, {{ 1 }});
108                    0x7: umlal({{
109                        uint64_t resTemp;
110                        resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
111                        resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
112                        Rd = (uint32_t)(resTemp & 0xffffffff);
113                        Rn = (uint32_t)(resTemp >> 32);
114                    }}, {{ 1 }}, {{ 1 }});
115                }
116                1: decode PUBWL {
117                    0x10: WarnUnimpl::swp();
118                    0x14: WarnUnimpl::swpb();
119                    0x18: WarnUnimpl::strex();
120                    0x19: WarnUnimpl::ldrex();
121                }
122            }
123            0xb: decode PUBWL {
124                format ArmStoreMemory {
125                    0x0, 0x8: strh_({{ Mem.uh = Rd.uh;
126                                       Rn = Rn + Rm; }},
127                                    {{ EA = Rn; }});
128                    0x4, 0xc: strh_il({{ Mem.uh = Rd.uh;
129                                         Rn = Rn + hilo; }},
130                                      {{ EA = Rn; }});
131                    0x10, 0x18: strh_p({{ Mem.uh = Rd.uh; }},
132                                       {{ EA = Rn + Rm; }});
133                    0x12, 0x1a: strh_pw({{ Mem.uh = Rd.uh;
134                                           Rn = Rn + Rm; }},
135                                        {{ EA = Rn + Rm; }});
136                    0x14, 0x1c: strh_pil({{ Mem.uh = Rd.uh; }},
137                                         {{ EA = Rn + hilo; }});
138                    0x16, 0x1e: strh_piwl({{ Mem.uh = Rd.uh;
139                                             Rn = Rn + hilo; }},
140                                          {{ EA = Rn + hilo; }});
141                }
142                format ArmLoadMemory {
143                    0x1, 0x9: ldrh_l({{ Rd.uh = Mem.uh;
144                                        Rn = Rn + Rm; }},
145                                     {{ EA = Rn; }});
146                    0x5, 0xd: ldrh_il({{ Rd.uh = Mem.uh;
147                                         Rn = Rn + hilo; }},
148                                      {{ EA = Rn; }});
149                    0x11, 0x19: ldrh_pl({{ Rd.uh = Mem.uh; }},
150                                        {{ EA = Rn + Rm; }});
151                    0x13, 0x1b: ldrh_pwl({{ Rd.uh = Mem.uh;
152                                            Rn = Rn + Rm; }},
153                                         {{ EA = Rn + Rm; }});
154                    0x15, 0x1d: ldrh_pil({{ Rd.uh = Mem.uh; }},
155                                         {{ EA = Rn + hilo; }});
156                    0x17, 0x1f: ldrh_piwl({{ Rd.uh = Mem.uh;
157                                             Rn = Rn + hilo; }},
158                                          {{ EA = Rn + hilo; }});
159                }
160            }
161            format ArmLoadMemory {
162                0xd: decode PUBWL {
163                    0x1: ldrsb_l({{ Rd = Mem.sb;
164                                    Rn = Rn + Rm; }},
165                                 {{ EA = Rn; }});
166                    0x5: ldrsb_il({{ Rd = Mem.sb;
167                                     Rn = Rn + hilo; }},
168                                  {{ EA = Rn; }});
169                    0x9: ldrsb_ul({{ Rd = Mem.sb;
170                                     Rn = Rn - Rm; }},
171                                  {{ EA = Rn; }});
172                    0xd: ldrsb_uil({{ Rd = Mem.sb;
173                                      Rn = Rn - hilo; }},
174                                   {{ EA = Rn; }});
175                    0x11: ldrsb_pl({{ Rd = Mem.sb; }},
176                                   {{ EA = Rn + Rm; }});
177                    0x13: ldrsb_pwl({{ Rd = Mem.sb;
178                                       Rn = Rn + Rm; }},
179                                    {{ EA = Rn + Rm; }});
180                    0x15: ldrsb_pil({{ Rd = Mem.sb; }},
181                                    {{ EA = Rn + hilo; }});
182                    0x17: ldrsb_piwl({{ Rd = Mem.sb;
183                                        Rn = Rn + hilo; }},
184                                     {{ EA = Rn + hilo; }});
185                    0x19: ldrsb_pul({{ Rd = Mem.sb; }},
186                                    {{ EA = Rn - Rm; }});
187                    0x1b: ldrsb_puwl({{ Rd = Mem.sb;
188                                        Rn = Rn - Rm; }},
189                                     {{ EA = Rn - Rm; }});
190                    0x1d: ldrsb_puil({{ Rd = Mem.sb; }},
191                                     {{ EA = Rn - hilo; }});
192                    0x1f: ldrsb_puiwl({{ Rd = Mem.sb;
193                                         Rn = Rn - hilo; }},
194                                      {{ EA = Rn - hilo; }});
195                }
196                0xf: decode PUBWL {
197                    0x1: ldrsh_l({{ Rd = Mem.sh;
198                                    Rn = Rn + Rm; }},
199                                 {{ EA = Rn; }});
200                    0x5: ldrsh_il({{ Rd = Mem.sh;
201                                     Rn = Rn + hilo; }},
202                                  {{ EA = Rn; }});
203                    0x9: ldrsh_ul({{ Rd = Mem.sh;
204                                     Rn = Rn - Rm; }},
205                                  {{ EA = Rn; }});
206                    0xd: ldrsh_uil({{ Rd = Mem.sh;
207                                      Rn = Rn - hilo; }},
208                                   {{ EA = Rn; }});
209                    0x11: ldrsh_pl({{ Rd = Mem.sh; }},
210                                   {{ EA = Rn + Rm; }});
211                    0x13: ldrsh_pwl({{ Rd = Mem.sh;
212                                       Rn = Rn + Rm; }},
213                                    {{ EA = Rn + Rm; }});
214                    0x15: ldrsh_pil({{ Rd = Mem.sh; }},
215                                    {{ EA = Rn + hilo; }});
216                    0x17: ldrsh_piwl({{ Rd = Mem.sh;
217                                        Rn = Rn + hilo; }},
218                                     {{ EA = Rn + hilo; }});
219                    0x19: ldrsh_pul({{ Rd = Mem.sh; }},
220                                    {{ EA = Rn - Rm; }});
221                    0x1b: ldrsh_puwl({{ Rd = Mem.sh;
222                                        Rn = Rn - Rm; }},
223                                     {{ EA = Rn - Rm; }});
224                    0x1d: ldrsh_puil({{ Rd = Mem.sh; }},
225                                     {{ EA = Rn - hilo; }});
226                    0x1f: ldrsh_puiwl({{ Rd = Mem.sh;
227                                         Rn = Rn - hilo; }},
228                                      {{ EA = Rn - hilo; }});
229                }
230            }
231        }
232        0: decode IS_MISC {
233            0: decode OPCODE {
234                0x0: and({{ uint32_t resTemp;
235                            Rd = resTemp = Rn & op2; }},
236                         {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
237                         {{ Cpsr<28:> }});
238                0x1: eor({{ uint32_t resTemp;
239                            Rd = resTemp = Rn ^ op2; }},
240                         {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
241                         {{ Cpsr<28:> }});
242                0x2: sub({{ uint32_t resTemp, val2 = op2;
243                            Rd = resTemp = Rn - val2; }},
244                         {{ arm_sub_carry(resTemp, Rn, val2) }},
245                         {{ arm_sub_overflow(resTemp, Rn, val2) }});
246                0x3: rsb({{ uint32_t resTemp, val2 = op2;
247                            Rd = resTemp = val2 - Rn; }},
248                         {{ arm_sub_carry(resTemp, val2, Rn) }},
249                         {{ arm_sub_overflow(resTemp, val2, Rn) }});
250                0x4: add({{ uint32_t resTemp, val2 = op2;
251                            Rd = resTemp = Rn + val2; }},
252                         {{ arm_add_carry(resTemp, Rn, val2) }},
253                         {{ arm_add_overflow(resTemp, Rn, val2) }});
254                0x5: adc({{ uint32_t resTemp, val2 = op2;
255                            Rd = resTemp = Rn + val2 + Cpsr<29:>; }},
256                         {{ arm_add_carry(resTemp, Rn, val2) }},
257                         {{ arm_add_overflow(resTemp, Rn, val2) }});
258                0x6: sbc({{ uint32_t resTemp, val2 = op2;
259                            Rd = resTemp = Rn - val2 - !Cpsr<29:>; }},
260                         {{ arm_sub_carry(resTemp, Rn, val2) }},
261                         {{ arm_sub_overflow(resTemp, Rn, val2) }});
262                0x7: rsc({{ uint32_t resTemp, val2 = op2;
263                            Rd = resTemp = val2 - Rn - !Cpsr<29:>; }},
264                         {{ arm_sub_carry(resTemp, val2, Rn) }},
265                         {{ arm_sub_overflow(resTemp, val2, Rn) }});
266                0x8: tst({{ uint32_t resTemp = Rn & op2; }},
267                         {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
268                         {{ Cpsr<28:> }});
269                0x9: teq({{ uint32_t resTemp = Rn ^ op2; }},
270                         {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
271                         {{ Cpsr<28:> }});
272                0xa: cmp({{ uint32_t resTemp, val2 = op2;
273                            resTemp = Rn - val2; }},
274                         {{ arm_sub_carry(resTemp, Rn, val2) }},
275                         {{ arm_sub_overflow(resTemp, Rn, val2) }});
276                0xb: cmn({{ uint32_t resTemp, val2 = op2;
277                            resTemp = Rn + val2; }},
278                         {{ arm_add_carry(resTemp, Rn, val2) }},
279                         {{ arm_add_overflow(resTemp, Rn, val2) }});
280                0xc: orr({{ uint32_t resTemp, val2 = op2;
281                            Rd = resTemp = Rn | val2; }},
282                         {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
283                         {{ Cpsr<28:> }});
284                0xd: mov({{ uint32_t resTemp;
285                            Rd = resTemp = op2; }},
286                         {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
287                         {{ Cpsr<28:> }});
288                0xe: bic({{ uint32_t resTemp;
289                            Rd = resTemp = Rn & ~op2; }},
290                         {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
291                         {{ Cpsr<28:> }});
292                0xf: mvn({{ uint32_t resTemp;
293                            Rd = resTemp = ~op2; }},
294                         {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }},
295                         {{ Cpsr<28:> }});
296            }
297            1: decode MISC_OPCODE {
298                0x0: decode OPCODE {
299                    0x8: WarnUnimpl::mrs_cpsr();
300                    0x9: WarnUnimpl::msr_cpsr();
301                    0xa: WarnUnimpl::mrs_spsr();
302                    0xb: WarnUnimpl::msr_spsr();
303                }
304                0x1: decode OPCODE {
305                    0x9: BranchExchange::bx({{ }});
306                    0xb: PredOp::clz({{
307                        if (Rm == 0)
308                            Rd = 32;
309                        else
310                        {
311                            int i;
312                            for (i = 0; i < 32; i++)
313                            {
314                                if (Rm & (1<<(31-i)))
315                                break;
316                            }
317                            Rd = i;
318                        }
319                    }});
320                }
321                0x2: decode OPCODE {
322                    0x9: WarnUnimpl::bxj();
323                }
324                0x3: decode OPCODE {
325                    0x9: BranchExchange::blx({{ }}, Link);
326                }
327                0x5: decode OPCODE {
328                    0x8: WarnUnimpl::qadd();
329                    0x9: WarnUnimpl::qsub();
330                    0xa: WarnUnimpl::qdadd();
331                    0xb: WarnUnimpl::qdsub();
332                }
333                0x8: decode OPCODE {
334                    0x8: WarnUnimpl::smlabb();
335                    0x9: WarnUnimpl::smlalbb();
336                    0xa: WarnUnimpl::smlawb();
337                    0xb: WarnUnimpl::smulbb();
338                }
339                0xa: decode OPCODE {
340                    0x8: WarnUnimpl::smlatb();
341                    0x9: WarnUnimpl::smulwb();
342                    0xa: WarnUnimpl::smlaltb();
343                    0xb: WarnUnimpl::smultb();
344                }
345                0xc: decode OPCODE {
346                    0x8: WarnUnimpl::smlabt();
347                    0x9: WarnUnimpl::smlawt();
348                    0xa: WarnUnimpl::smlalbt();
349                    0xb: WarnUnimpl::smulbt();
350                }
351                0xe: decode OPCODE {
352                    0x8: WarnUnimpl::smlatt();
353                    0x9: WarnUnimpl::smulwt();
354                    0xa: WarnUnimpl::smlaltt();
355                    0xb: WarnUnimpl::smultt();
356                }
357            }
358        }
359    }
360    0x1: decode IS_MISC {
361        0: decode S_FIELD {
362            0: decode OPCODE {
363                format PredImmOp {
364                    0x0: andi({{ Rd = Rn & rotated_imm; }});
365                    0x1: eori({{ Rd = Rn ^ rotated_imm; }});
366                    0x2: subi({{ Rd = Rn - rotated_imm; }});
367                    0x3: rsbi({{ Rd = rotated_imm - Rn; }});
368                    0x4: addi({{ Rd = Rn + rotated_imm; }});
369                    0x5: adci({{ Rd = Rn + rotated_imm + Cpsr<29:>; }});
370                    0x6: sbci({{ Rd = Rn - rotated_imm + Cpsr<29:> - 1; }});
371                    0x7: rsci({{ Rd = rotated_imm - Rn + Cpsr<29:> - 1; }});
372                    0xc: orri({{ Rd = Rn | rotated_imm; }});
373                    0xd: decode RN {
374                        0: movi({{ Rd = rotated_imm; }});
375                    }
376                    0xe: bici({{ Rd = Rn & ~rotated_imm; }});
377                    0xf: decode RN {
378                        0: mvni({{ Rd = ~rotated_imm; }});
379                    }
380                }
381            }
382            1: decode OPCODE {
383                format PredImmOpCc {
384                    0x0: andsi({{
385                        uint32_t resTemp;
386                        Rd = resTemp = Rn & rotated_imm;
387                        }},
388                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
389                        {{ Cpsr<28:> }});
390                    0x1: eorsi({{
391                        uint32_t resTemp;
392                        Rd = resTemp = Rn ^ rotated_imm;
393                        }},
394                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
395                        {{ Cpsr<28:> }});
396                    0x2: subsi({{
397                        uint32_t resTemp;
398                        Rd = resTemp = Rn - rotated_imm;
399                        }},
400                        {{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
401                        {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
402                    0x3: rsbsi({{
403                        uint32_t resTemp;
404                        Rd = resTemp = rotated_imm - Rn;
405                        }},
406                        {{ arm_sub_carry(resTemp, rotated_imm, Rn) }},
407                        {{ arm_sub_overflow(resTemp, rotated_imm, Rn) }});
408                    0x4: addsi({{
409                        uint32_t resTemp;
410                        Rd = resTemp = Rn + rotated_imm;
411                        }},
412                        {{ arm_add_carry(resTemp, Rn, rotated_imm) }},
413                        {{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
414                    0x5: adcsi({{
415                        uint32_t resTemp;
416                        Rd = resTemp = Rn + rotated_imm + Cpsr<29:>;
417                        }},
418                        {{ arm_add_carry(resTemp, Rn, rotated_imm) }},
419                        {{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
420                    0x6: sbcsi({{
421                        uint32_t resTemp;
422                        Rd = resTemp = Rn -rotated_imm + Cpsr<29:> - 1;
423                        }},
424                        {{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
425                        {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
426                    0x7: rscsi({{
427                        uint32_t resTemp;
428                        Rd = resTemp = rotated_imm - Rn + Cpsr<29:> - 1;
429                        }},
430                        {{ arm_sub_carry(resTemp, rotated_imm, Rn) }},
431                        {{ arm_sub_overflow(resTemp, rotated_imm, Rn) }});
432                    0x8: tsti({{
433                        uint32_t resTemp;
434                        resTemp = Rn & rotated_imm;
435                        }},
436                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
437                        {{ Cpsr<28:> }});
438                    0x9: teqi({{
439                        uint32_t resTemp;
440                        resTemp = Rn ^ rotated_imm;
441                        }},
442                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
443                        {{ Cpsr<28:> }});
444                    0xa: cmpi({{
445                        uint32_t resTemp;
446                        resTemp = Rn - rotated_imm;
447                        }},
448                        {{ arm_sub_carry(resTemp, Rn, rotated_imm) }},
449                        {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }});
450                    0xb: cmni({{
451                        uint32_t resTemp;
452                        resTemp = Rn + rotated_imm;
453                        }},
454                        {{ arm_add_carry(resTemp, Rn, rotated_imm) }},
455                        {{ arm_add_overflow(resTemp, Rn, rotated_imm) }});
456                    0xc: orrsi({{
457                        uint32_t resTemp;
458                        Rd = resTemp = Rn | rotated_imm;
459                        }},
460                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
461                        {{ Cpsr<28:> }});
462                    0xd: movsi({{
463                        uint32_t resTemp;
464                        Rd = resTemp = rotated_imm;
465                        }},
466                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
467                        {{ Cpsr<28:> }});
468                    0xe: bicsi({{
469                        uint32_t resTemp;
470                        Rd = resTemp = Rn & ~rotated_imm;
471                        }},
472                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
473                        {{ Cpsr<28:> }});
474                    0xf: mvnsi({{
475                        uint32_t resTemp;
476                        Rd = resTemp = ~rotated_imm;
477                        }},
478                        {{ (rotate ? rotated_carry:Cpsr<29:>) }},
479                        {{ Cpsr<28:> }});
480                }
481            }
482        }
483        1: decode OPCODE {
484            // The following two instructions aren't supposed to be defined
485            0x8: WarnUnimpl::undefined_instruction();
486            0x9: WarnUnimpl::undefined_instruction();
487
488            0xa: WarnUnimpl::mrs_i_cpsr();
489            0xb: WarnUnimpl::mrs_i_spsr();
490        }
491    }
492    0x2: decode PUBWL {
493        // CAREFUL:
494        // Can always do EA + disp, since we negate disp using the UP flag
495        // Post-indexed variants
496        0x00,0x08: ArmStoreMemory::str_({{ Mem = Rd;
497                                           Rn = Rn + disp; }},
498                                        {{ EA = Rn; }});
499        0x01,0x09: ArmLoadMemory::ldr_l({{ Rn = Rn + disp; 
500                                           Rd = Mem; }},
501                                        {{ EA = Rn; }});
502        0x04,0x0c: ArmStoreMemory::strb_b({{ Mem.ub = Rd.ub;
503                                             Rn = Rn + disp; }},
504                                          {{ EA = Rn; }});
505        0x05,0x0d: ArmLoadMemory::ldrb_bl({{ Rn = Rn + disp; 
506                                             Rd.ub = Mem.ub; }},
507                                          {{ EA = Rn; }});
508        // Pre-indexed variants
509        0x10,0x18: ArmStoreMemory::str_p({{ Mem = Rd; }});
510        0x11,0x19: ArmLoadMemory::ldr_pl({{ Rd = Mem; }});
511        0x12,0x1a: ArmStoreMemory::str_pw({{ Mem = Rd;
512                                             Rn = Rn + disp; }});
513        0x13,0x1b: ArmLoadMemory::ldr_pwl({{ Rn = Rn + disp; 
514                                             Rd = Mem; }});
515        0x14,0x1c: ArmStoreMemory::strb_pb({{ Mem.ub = Rd.ub; }});
516        0x15,0x1d: ArmLoadMemory::ldrb_pbl({{ Rd.ub = Mem.ub; }});
517        0x16,0x1e: ArmStoreMemory::strb_pbw({{ Mem.ub = Rd.ub;
518                                               Rn = Rn + disp; }});
519        0x17,0x1f: ArmLoadMemory::ldrb_pbwl({{ Rn = Rn + disp; 
520                                               Rd.ub = Mem.ub; }});
521    }
522    0x3: decode OPCODE_4 {
523        0: decode PUBWL {
524            0x00,0x08: ArmStoreMemory::strr_({{
525                    Mem = Rd;
526                    Rn = Rn + Rm_Imm; }},
527                 {{ EA = Rn; }});
528            0x01,0x09: ArmLoadMemory::ldrr_l({{
529                    Rd = Mem;
530                    Rn = Rn + Rm_Imm; }},
531                 {{ EA = Rn; }});
532            0x04,0x0c: ArmStoreMemory::strr_b({{
533                    Mem.ub = Rd.ub;
534                    Rn = Rn + Rm_Imm; }},
535                 {{ EA = Rn; }});
536            0x05,0x0d: ArmLoadMemory::ldrr_bl({{
537                    Rd.ub = Mem.ub;
538                    Rn = Rn + Rm_Imm; }},
539                 {{ EA = Rn; }});
540            0x10,0x18: ArmStoreMemory::strr_p({{
541                    Mem = Rd; }},
542                 {{ EA = Rn + Rm_Imm; }});
543            0x11,0x19: ArmLoadMemory::ldrr_pl({{
544                    Rd = Mem; }},
545                 {{ EA = Rn + Rm_Imm; }});
546            0x12,0x1a: ArmStoreMemory::strr_pw({{
547                    Mem = Rd;
548                    Rn = Rn + Rm_Imm; }},
549                 {{ EA = Rn + Rm_Imm; }});
550            0x13,0x1b: ArmLoadMemory::ldrr_pwl({{
551                    Rd = Mem;
552                    Rn = Rn + Rm_Imm; }},
553                 {{ EA = Rn + Rm_Imm; }});
554            0x14,0x1c: ArmStoreMemory::strr_pb({{
555                    Mem.ub = Rd.ub; }},
556                 {{ EA = Rn + Rm_Imm; }});
557            0x15,0x1d: ArmLoadMemory::ldrr_pbl({{
558                    Rd.ub = Mem.ub; }},
559                 {{ EA = Rn + Rm_Imm; }});
560            0x16,0x1e: ArmStoreMemory::strr_pbw({{
561                    Mem.ub = Rd.ub;
562                    Rn = Rn + Rm_Imm; }},
563                 {{ EA = Rn + Rm_Imm; }});
564            0x17,0x1f: ArmLoadMemory::ldrr_pbwl({{
565                    Rd.ub = Mem.ub;
566                    Rn = Rn + Rm_Imm; }},
567                 {{ EA = Rn + Rm_Imm; }});
568        }
569    }
570    0x4: decode PUSWL {
571        // Right now we only handle cases when S (PSRUSER) is not set
572        default: ArmMacroStore::ldmstm({{ }});
573    }
574    0x5: decode OPCODE_24 {
575        // Branch (and Link) Instructions
576        0: Branch::b({{ }});
577        1: Branch::bl({{ }}, Link);
578    }
579    0x6: decode CPNUM {
580        0x1: decode PUNWL {
581            0x02,0x0a: decode OPCODE_15 {
582                0: ArmStoreMemory::stfs_({{ Mem.sf = Fd.sf;
583                                            Rn = Rn + disp8; }},
584                    {{ EA = Rn; }});
585                1: ArmMacroFPAOp::stfd_({{ }});
586            }
587            0x03,0x0b: decode OPCODE_15 {
588                0: ArmLoadMemory::ldfs_({{ Fd.sf = Mem.sf;
589                                           Rn = Rn + disp8; }},
590                    {{ EA = Rn; }});
591                1: ArmMacroFPAOp::ldfd_({{ }});
592            }
593            0x06,0x0e: decode OPCODE_15 {
594                0: ArmMacroFPAOp::stfe_nw({{ }});
595            }
596            0x07,0x0f: decode OPCODE_15 {
597                0: ArmMacroFPAOp::ldfe_nw({{ }});
598            }
599            0x10,0x18: decode OPCODE_15 {
600                0: ArmStoreMemory::stfs_p({{ Mem.sf = Fd.sf; }},
601                    {{ EA = Rn + disp8; }});
602                1: ArmMacroFPAOp::stfd_p({{ }});
603            }
604            0x11,0x19: decode OPCODE_15 {
605                0: ArmLoadMemory::ldfs_p({{ Fd.sf = Mem.sf; }},
606                    {{ EA = Rn + disp8; }});
607                1: ArmMacroFPAOp::ldfd_p({{ }});
608            }
609            0x12,0x1a: decode OPCODE_15 {
610                0: ArmStoreMemory::stfs_pw({{ Mem.sf = Fd.sf;
611                                              Rn = Rn + disp8; }},
612                    {{ EA = Rn + disp8; }});
613                1: ArmMacroFPAOp::stfd_pw({{ }});
614            }
615            0x13,0x1b: decode OPCODE_15 {
616                0: ArmLoadMemory::ldfs_pw({{ Fd.sf = Mem.sf;
617                                             Rn = Rn + disp8; }},
618                    {{ EA = Rn + disp8; }});
619                1: ArmMacroFPAOp::ldfd_pw({{ }});
620            }
621            0x14,0x1c: decode OPCODE_15 {
622                0: ArmMacroFPAOp::stfe_pn({{ }});
623            }
624            0x15,0x1d: decode OPCODE_15 {
625                0: ArmMacroFPAOp::ldfe_pn({{ }});
626            }
627            0x16,0x1e: decode OPCODE_15 {
628                0: ArmMacroFPAOp::stfe_pnw({{ }});
629            }
630            0x17,0x1f: decode OPCODE_15 {
631                0: ArmMacroFPAOp::ldfe_pnw({{ }});
632            }
633        }
634        0x2: decode PUNWL {
635            // could really just decode as a single instruction
636            0x00,0x04,0x08,0x0c: ArmMacroFMOp::sfm_({{ }});
637            0x01,0x05,0x09,0x0d: ArmMacroFMOp::lfm_({{ }});
638            0x02,0x06,0x0a,0x0e: ArmMacroFMOp::sfm_w({{ }});
639            0x03,0x07,0x0b,0x0f: ArmMacroFMOp::lfm_w({{ }});
640            0x10,0x14,0x18,0x1c: ArmMacroFMOp::sfm_p({{ }});
641            0x11,0x15,0x19,0x1d: ArmMacroFMOp::lfm_p({{ }});
642            0x12,0x16,0x1a,0x1e: ArmMacroFMOp::sfm_pw({{ }});
643            0x13,0x17,0x1b,0x1f: ArmMacroFMOp::lfm_pw({{ }});
644        }
645    }
646    0x7: decode OPCODE_24 {
647        0: decode CPNUM {
648            // Coprocessor Instructions
649            0x1: decode OPCODE_4 {
650                format FloatOp {
651                    // Basic FPA Instructions
652                    0: decode OPCODE_23_20 {
653                        0x0: decode OPCODE_15 {
654                            0: adf({{ Fd.sf = Fn.sf + Fm.sf; }});
655                            1: mvf({{ Fd.sf = Fm.sf; }});
656                        }
657                        0x1: decode OPCODE_15 {
658                            0: muf({{ Fd.sf = Fn.sf * Fm.sf; }});
659                            1: mnf({{ Fd.sf = -Fm.sf; }});
660                        }
661                        0x2: decode OPCODE_15 {
662                            0: suf({{ Fd.sf = Fn.sf - Fm.sf; }});
663                            1: abs({{ Fd.sf = fabs(Fm.sf); }});
664                        }
665                        0x3: decode OPCODE_15 {
666                            0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }});
667                            1: rnd({{ Fd.sf = rint(Fm.sf); }});
668                        }
669                        0x4: decode OPCODE_15 {
670                            0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }});
671                            1: sqt({{ Fd.sf = sqrt(Fm.sf); }});
672                        }
673                        0x5: decode OPCODE_15 {
674                            0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }});
675                            1: log({{ Fd.sf = log10(Fm.sf); }});
676                        }
677                        0x6: decode OPCODE_15 {
678                            0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }});
679                            1: lgn({{ Fd.sf = log(Fm.sf); }});
680                        }
681                        0x7: decode OPCODE_15 {
682                            0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }});
683                            1: exp({{ Fd.sf = exp(Fm.sf); }});
684                        }
685                        0x8: decode OPCODE_15 {
686                            0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }});
687                            1: sin({{ Fd.sf = sin(Fm.sf); }});
688                        }
689                        0x9: decode OPCODE_15 {
690                            0: fml({{ Fd.sf = Fn.sf * Fm.sf; }});
691                            1: cos({{ Fd.sf = cos(Fm.sf); }});
692                        }
693                        0xa: decode OPCODE_15 {
694                            0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }});
695                            1: tan({{ Fd.sf = tan(Fm.sf); }});
696                        }
697                        0xb: decode OPCODE_15 {
698                            0: frd({{ Fd.sf = Fm.sf / Fn.sf; }});
699                            1: asn({{ Fd.sf = asin(Fm.sf); }});
700                        }
701                        0xc: decode OPCODE_15 {
702                            0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }});
703                            1: acs({{ Fd.sf = acos(Fm.sf); }});
704                        }
705                        0xd: decode OPCODE_15 {
706                            1: atn({{ Fd.sf = atan(Fm.sf); }});
707                        }
708                        0xe: decode OPCODE_15 {
709                            // Unnormalised Round
710                            1: FailUnimpl::urd();
711                        }
712                        0xf: decode OPCODE_15 {
713                            // Normalise
714                            1: FailUnimpl::nrm();
715                        }
716                    }
717                    1: decode OPCODE_15_12 {
718                        0xf: decode OPCODE_23_21 {
719                            format FloatCmp {
720                                0x4: cmf({{ Fn.df }}, {{ Fm.df }});
721                                0x5: cnf({{ Fn.df }}, {{ -Fm.df }});
722                                0x6: cmfe({{ Fn.df }}, {{ Fm.df}});
723                                0x7: cnfe({{ Fn.df }}, {{ -Fm.df}});
724                            }
725                        }
726                        default: decode OPCODE_23_20 {
727                            0x0: decode OPCODE_7 {
728                                0: flts({{ Fn.sf = (float) Rd.sw; }});
729                                1: fltd({{ Fn.df = (double) Rd.sw; }});
730                            }
731                            0x1: decode OPCODE_7 {
732                                0: fixs({{ Rd = (uint32_t) Fm.sf; }});
733                                1: fixd({{ Rd = (uint32_t) Fm.df; }});
734                            }
735                            0x2: wfs({{ Fpsr = Rd; }});
736                            0x3: rfs({{ Rd = Fpsr; }});
737                            0x4: FailUnimpl::wfc();
738                            0x5: FailUnimpl::rfc();
739                        }
740                    }
741                }
742            }
743        }
744        format PredOp {
745            // ARM System Call (SoftWare Interrupt)
746            1: swi({{ if (testPredicate(Cpsr, condCode))
747                      {
748                          xc->syscall(IMMED_23_0);
749                      }
750            }});
751        }
752    }
753}
754}
755}
756
757