arm.isa revision 6269
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        1: decode MEDIA_OPCODE {
570            0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7: WarnUnimpl::parallel_add_subtract_instructions();
571            0x8: decode MISC_OPCODE {
572                0x1, 0x9: WarnUnimpl::pkhbt();
573                0x7: WarnUnimpl::sxtab16();
574                0xb: WarnUnimpl::sel();
575                0x5, 0xd: WarnUnimpl::pkhtb();
576                0x3: WarnUnimpl::sign_zero_extend_add();
577            }
578            0xa, 0xb: decode SHIFT {
579                0x0, 0x2: WarnUnimpl::ssat();
580                0x1: WarnUnimpl::ssat16();
581            }
582            0xe, 0xf: decode SHIFT {
583                0x0, 0x2: WarnUnimpl::usat();
584                0x1: WarnUnimpl::usat16();
585            }
586            0x10: decode RN {
587                0xf: decode MISC_OPCODE {
588                    0x1: WarnUnimpl::smuad();
589                    0x3: WarnUnimpl::smuadx();
590                    0x5: WarnUnimpl::smusd();
591                    0x7: WarnUnimpl::smusdx();
592                }
593                default: decode MISC_OPCODE {
594                    0x1: WarnUnimpl::smlad();
595                    0x3: WarnUnimpl::smladx();
596                    0x5: WarnUnimpl::smlsd();
597                    0x7: WarnUnimpl::smlsdx();
598                }
599            }
600            0x14: decode MISC_OPCODE {
601                0x1: WarnUnimpl::smlald();
602                0x3: WarnUnimpl::smlaldx();
603                0x5: WarnUnimpl::smlsld();
604                0x7: WarnUnimpl::smlsldx();
605            }
606            0x15: decode RN {
607                0xf: decode MISC_OPCODE {
608                    0x1: WarnUnimpl::smmul();
609                    0x3: WarnUnimpl::smmulr();
610                }
611                default: decode MISC_OPCODE {
612                    0x1: WarnUnimpl::smmla();
613                    0x3: WarnUnimpl::smmlar();
614                    0xd: WarnUnimpl::smmls();
615                    0xf: WarnUnimpl::smmlsr();
616                }
617            }
618            0x18: decode RN {
619                0xf: WarnUnimpl::usada8();
620                default: WarnUnimpl::usad8();
621            }
622        }
623    }
624    0x4: decode PUSWL {
625        // Right now we only handle cases when S (PSRUSER) is not set
626        default: ArmMacroStore::ldmstm({{ }});
627    }
628    0x5: decode OPCODE_24 {
629        // Branch (and Link) Instructions
630        0: Branch::b({{ }});
631        1: Branch::bl({{ }}, Link);
632    }
633    0x6: decode CPNUM {
634        0x1: decode PUNWL {
635            0x02,0x0a: decode OPCODE_15 {
636                0: ArmStoreMemory::stfs_({{ Mem.sf = Fd.sf;
637                                            Rn = Rn + disp8; }},
638                    {{ EA = Rn; }});
639                1: ArmMacroFPAOp::stfd_({{ }});
640            }
641            0x03,0x0b: decode OPCODE_15 {
642                0: ArmLoadMemory::ldfs_({{ Fd.sf = Mem.sf;
643                                           Rn = Rn + disp8; }},
644                    {{ EA = Rn; }});
645                1: ArmMacroFPAOp::ldfd_({{ }});
646            }
647            0x06,0x0e: decode OPCODE_15 {
648                0: ArmMacroFPAOp::stfe_nw({{ }});
649            }
650            0x07,0x0f: decode OPCODE_15 {
651                0: ArmMacroFPAOp::ldfe_nw({{ }});
652            }
653            0x10,0x18: decode OPCODE_15 {
654                0: ArmStoreMemory::stfs_p({{ Mem.sf = Fd.sf; }},
655                    {{ EA = Rn + disp8; }});
656                1: ArmMacroFPAOp::stfd_p({{ }});
657            }
658            0x11,0x19: decode OPCODE_15 {
659                0: ArmLoadMemory::ldfs_p({{ Fd.sf = Mem.sf; }},
660                    {{ EA = Rn + disp8; }});
661                1: ArmMacroFPAOp::ldfd_p({{ }});
662            }
663            0x12,0x1a: decode OPCODE_15 {
664                0: ArmStoreMemory::stfs_pw({{ Mem.sf = Fd.sf;
665                                              Rn = Rn + disp8; }},
666                    {{ EA = Rn + disp8; }});
667                1: ArmMacroFPAOp::stfd_pw({{ }});
668            }
669            0x13,0x1b: decode OPCODE_15 {
670                0: ArmLoadMemory::ldfs_pw({{ Fd.sf = Mem.sf;
671                                             Rn = Rn + disp8; }},
672                    {{ EA = Rn + disp8; }});
673                1: ArmMacroFPAOp::ldfd_pw({{ }});
674            }
675            0x14,0x1c: decode OPCODE_15 {
676                0: ArmMacroFPAOp::stfe_pn({{ }});
677            }
678            0x15,0x1d: decode OPCODE_15 {
679                0: ArmMacroFPAOp::ldfe_pn({{ }});
680            }
681            0x16,0x1e: decode OPCODE_15 {
682                0: ArmMacroFPAOp::stfe_pnw({{ }});
683            }
684            0x17,0x1f: decode OPCODE_15 {
685                0: ArmMacroFPAOp::ldfe_pnw({{ }});
686            }
687        }
688        0x2: decode PUNWL {
689            // could really just decode as a single instruction
690            0x00,0x04,0x08,0x0c: ArmMacroFMOp::sfm_({{ }});
691            0x01,0x05,0x09,0x0d: ArmMacroFMOp::lfm_({{ }});
692            0x02,0x06,0x0a,0x0e: ArmMacroFMOp::sfm_w({{ }});
693            0x03,0x07,0x0b,0x0f: ArmMacroFMOp::lfm_w({{ }});
694            0x10,0x14,0x18,0x1c: ArmMacroFMOp::sfm_p({{ }});
695            0x11,0x15,0x19,0x1d: ArmMacroFMOp::lfm_p({{ }});
696            0x12,0x16,0x1a,0x1e: ArmMacroFMOp::sfm_pw({{ }});
697            0x13,0x17,0x1b,0x1f: ArmMacroFMOp::lfm_pw({{ }});
698        }
699    }
700    0x7: decode OPCODE_24 {
701        0: decode CPNUM {
702            // Coprocessor Instructions
703            0x1: decode OPCODE_4 {
704                format FloatOp {
705                    // Basic FPA Instructions
706                    0: decode OPCODE_23_20 {
707                        0x0: decode OPCODE_15 {
708                            0: adf({{ Fd.sf = Fn.sf + Fm.sf; }});
709                            1: mvf({{ Fd.sf = Fm.sf; }});
710                        }
711                        0x1: decode OPCODE_15 {
712                            0: muf({{ Fd.sf = Fn.sf * Fm.sf; }});
713                            1: mnf({{ Fd.sf = -Fm.sf; }});
714                        }
715                        0x2: decode OPCODE_15 {
716                            0: suf({{ Fd.sf = Fn.sf - Fm.sf; }});
717                            1: abs({{ Fd.sf = fabs(Fm.sf); }});
718                        }
719                        0x3: decode OPCODE_15 {
720                            0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }});
721                            1: rnd({{ Fd.sf = rint(Fm.sf); }});
722                        }
723                        0x4: decode OPCODE_15 {
724                            0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }});
725                            1: sqt({{ Fd.sf = sqrt(Fm.sf); }});
726                        }
727                        0x5: decode OPCODE_15 {
728                            0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }});
729                            1: log({{ Fd.sf = log10(Fm.sf); }});
730                        }
731                        0x6: decode OPCODE_15 {
732                            0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }});
733                            1: lgn({{ Fd.sf = log(Fm.sf); }});
734                        }
735                        0x7: decode OPCODE_15 {
736                            0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }});
737                            1: exp({{ Fd.sf = exp(Fm.sf); }});
738                        }
739                        0x8: decode OPCODE_15 {
740                            0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }});
741                            1: sin({{ Fd.sf = sin(Fm.sf); }});
742                        }
743                        0x9: decode OPCODE_15 {
744                            0: fml({{ Fd.sf = Fn.sf * Fm.sf; }});
745                            1: cos({{ Fd.sf = cos(Fm.sf); }});
746                        }
747                        0xa: decode OPCODE_15 {
748                            0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }});
749                            1: tan({{ Fd.sf = tan(Fm.sf); }});
750                        }
751                        0xb: decode OPCODE_15 {
752                            0: frd({{ Fd.sf = Fm.sf / Fn.sf; }});
753                            1: asn({{ Fd.sf = asin(Fm.sf); }});
754                        }
755                        0xc: decode OPCODE_15 {
756                            0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }});
757                            1: acs({{ Fd.sf = acos(Fm.sf); }});
758                        }
759                        0xd: decode OPCODE_15 {
760                            1: atn({{ Fd.sf = atan(Fm.sf); }});
761                        }
762                        0xe: decode OPCODE_15 {
763                            // Unnormalised Round
764                            1: FailUnimpl::urd();
765                        }
766                        0xf: decode OPCODE_15 {
767                            // Normalise
768                            1: FailUnimpl::nrm();
769                        }
770                    }
771                    1: decode OPCODE_15_12 {
772                        0xf: decode OPCODE_23_21 {
773                            format FloatCmp {
774                                0x4: cmf({{ Fn.df }}, {{ Fm.df }});
775                                0x5: cnf({{ Fn.df }}, {{ -Fm.df }});
776                                0x6: cmfe({{ Fn.df }}, {{ Fm.df}});
777                                0x7: cnfe({{ Fn.df }}, {{ -Fm.df}});
778                            }
779                        }
780                        default: decode OPCODE_23_20 {
781                            0x0: decode OPCODE_7 {
782                                0: flts({{ Fn.sf = (float) Rd.sw; }});
783                                1: fltd({{ Fn.df = (double) Rd.sw; }});
784                            }
785                            0x1: decode OPCODE_7 {
786                                0: fixs({{ Rd = (uint32_t) Fm.sf; }});
787                                1: fixd({{ Rd = (uint32_t) Fm.df; }});
788                            }
789                            0x2: wfs({{ Fpsr = Rd; }});
790                            0x3: rfs({{ Rd = Fpsr; }});
791                            0x4: FailUnimpl::wfc();
792                            0x5: FailUnimpl::rfc();
793                        }
794                    }
795                }
796            }
797        }
798        format PredOp {
799            // ARM System Call (SoftWare Interrupt)
800            1: swi({{ if (testPredicate(Cpsr, condCode))
801                      {
802                          xc->syscall(IMMED_23_0);
803                      }
804            }});
805        }
806    }
807}
808}
809}
810
811