thumb.isa revision 7124:50d26210c812
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder.  You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2009 The Regents of The University of Michigan
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Gabe Black
42
431: decode BIGTHUMB {
44    // 16 bit thumb instructions.
45    0: decode TOPCODE_15_13 {
46        0x0, 0x1: decode TOPCODE_13_11 {
47            0x0: WarnUnimpl::lsl(); //immediate
48            0x1: WarnUnimpl::lsr(); //immediate
49            0x2: WarnUnimpl::asr(); //immediate
50            0x3: decode TOPCODE_10_9 {
51                0x0: WarnUnimpl::add(); //register
52                0x1: WarnUnimpl::sub(); //register
53                0x2: WarnUnimpl::add(); //3 bit immediate
54                0x3: WarnUnimpl::sub(); //3 bit immediate
55            }
56            0x4: WarnUnimpl::mov(); //immediate
57            0x5: WarnUnimpl::cmp(); //immediate
58            0x6: WarnUnimpl::add(); //8 bit immediate, thumb
59            0x7: WarnUnimpl::sub(); //8 bit immediate, thumb
60        }
61        0x2: decode TOPCODE_12_10 {
62            // Data processing
63            0x0: decode TOPCODE_9_6 {
64                0x0: WarnUnimpl::and(); //register
65                0x1: WarnUnimpl::eor(); //register
66                0x2: WarnUnimpl::lsl(); //register
67                0x3: WarnUnimpl::lsr(); //register
68                0x4: WarnUnimpl::asr(); //register
69                0x5: WarnUnimpl::adc(); //register
70                0x6: WarnUnimpl::sbc(); //register
71                0x7: WarnUnimpl::ror(); //register
72                0x8: WarnUnimpl::tst(); //register
73                0x9: WarnUnimpl::rsb(); //immediate
74                0xa: WarnUnimpl::cmp(); //register (high registers)
75                0xb: WarnUnimpl::cmn(); //register
76                0xc: WarnUnimpl::orr(); //register
77                0xd: WarnUnimpl::mul();
78                0xe: WarnUnimpl::bic(); //register
79                0xf: WarnUnimpl::mvn(); //register
80            }
81            // Special data instructions and branch and exchange
82            0x1: decode TOPCODE_9_6 {
83                0x0: WarnUnimpl::add(); //register (low registers)
84                0x1, 0x2, 0x3: WarnUnimpl::add(); //register (high registers)
85                0x4: WarnUnimpl::unpredictable(); //?
86                0x5, 0x6, 0x7: WarnUnimpl::cmp(); //register
87                0x8: WarnUnimpl::mov(); //register (low registers)
88                0x9, 0xa, 0xb: WarnUnimpl::mov(); //register (high registers)
89                0xc, 0xd: WarnUnimpl::bx();
90                0xe, 0xf: WarnUnimpl::blx(); //register
91            }
92            0x2, 0x3: WarnUnimpl::ldr();
93            default: Thumb16MemReg::thumb16MemReg();
94        }
95        0x3: decode TOPCODE_12_11 {
96            0x0: WarnUnimpl::str(); //immediate, thumb
97            0x1: WarnUnimpl::ldr(); //immediate, thumb
98            0x2: WarnUnimpl::strb(); //immediate, thumb
99            0x3: WarnUnimpl::ldrb(); //immediate, thumb
100        }
101        0x4: decode TOPCODE_12_11 {
102            0x0: WarnUnimpl::strh(); //immediate, thumb
103            0x1: WarnUnimpl::ldrh(); //immediate, thumb
104            0x2: WarnUnimpl::str(); //immediate, thumb
105            0x3: WarnUnimpl::ldr(); //immediate, thumb
106        }
107        0x5: decode TOPCODE_12_11 {
108            0x0: WarnUnimpl::adr();
109            0x1: WarnUnimpl::add(); //sp, immediate
110            0x2: decode TOPCODE_10_8 {
111                0x0: decode TOPCODE_7 {
112                    0x0: WarnUnimpl::add(); //sp, immediate
113                    0x1: WarnUnimpl::sub(); //sp, immediate
114                }
115                0x1, 0x3: WarnUnimpl::cbz(); //cbnz too...
116                0x2: decode TOPCODE_7_6 {
117                    0x0: WarnUnimpl::sxth();
118                    0x1: WarnUnimpl::sxtb();
119                    0x2: WarnUnimpl::uxth();
120                    0x3: WarnUnimpl::uxtb();
121                }
122                0x4, 0x5: WarnUnimpl::pop();
123                0x6: decode TOPCODE_7_5 {
124                    0x2: WarnUnimpl::setend();
125                    0x3: WarnUnimpl::cps();
126                }
127            }
128            0x3: decode TOPCODE_10_8 {
129                0x1, 0x3: WarnUnimpl::cbz(); //cbnz too...
130                0x2: decode TOPCODE_7_6 {
131                    0x0: WarnUnimpl::rev();
132                    0x1: WarnUnimpl::rev16();
133                    0x3: WarnUnimpl::revsh();
134                }
135                0x4, 0x5: WarnUnimpl::pop();
136                0x6: WarnUnimpl::bkpt();
137                0x7: decode TOPCODE_3_0 {
138                    0x0: WarnUnimpl::it();
139                    default: decode TOPCODE_7_4 {
140                        0x0: WarnUnimpl::nop();
141                        0x1: WarnUnimpl::yield();
142                        0x2: WarnUnimpl::wfe();
143                        0x3: WarnUnimpl::wfi();
144                        0x4: WarnUnimpl::sev();
145                        default: WarnUnimpl::unallocated_hint();
146                    }
147                }
148            }
149        }
150        0x6: decode TOPCODE_12_11 {
151            0x0: WarnUnimpl::stm(); // also stmia, stmea
152            0x1: WarnUnimpl::ldm(); // also ldmia, ldmea
153            default: decode TOPCODE_11_8 {
154                0xe: WarnUnimpl::undefined(); // permanently undefined
155                0xf: WarnUnimpl::svc(); // formerly swi
156                default: WarnUnimpl::b(); // conditional
157            }
158        }
159        0x7: decode TOPCODE_12_11 {
160            0x0: WarnUnimpl::b(); // unconditional
161        }
162    }
163
164    // 32 bit thumb instructions.
165    1: decode HTOPCODE_12_11 {
166        0x1: decode HTOPCODE_10_9 {
167            0x0: decode HTOPCODE_8_6 {
168                0x0, 0x6: decode HTOPCODE_4 {
169                    0x0: WarnUnimpl::srs();
170                    0x1: WarnUnimpl::rfe();
171                }
172                0x1: decode HTOPCODE_5_4 {
173                    0x0: WarnUnimpl::strex();
174                    0x1: WarnUnimpl::ldrex();
175                    0x2: WarnUnimpl::strd(); // immediate
176                    0x3: decode HTRN {
177                        0xf: WarnUnimpl::ldrd(); // literal
178                        default: WarnUnimpl::ldrd(); // immediate
179                    }
180                }
181                0x2: decode HTOPCODE_4 {
182                    0x0: WarnUnimpl::stm(); // stmia, stmea
183                    0x1: decode HTRN {
184                        0xd: WarnUnimpl::pop();
185                        default: WarnUnimpl::ldm(); // ldmia, ldmfd
186                    }
187                }
188                0x3: decode HTOPCODE_5_4 {
189                    0x0: decode LTOPCODE_7_4 {
190                        0x4: WarnUnimpl::strexb();
191                        0x5: WarnUnimpl::strexh();
192                        0x7: WarnUnimpl::strexd();
193                    }
194                    0x1: decode LTOPCODE_7_4 {
195                        0x0: WarnUnimpl::tbb();
196                        0x1: WarnUnimpl::tbh();
197                        0x4: WarnUnimpl::ldrexb();
198                        0x5: WarnUnimpl::ldrexh();
199                        0x7: WarnUnimpl::ldrexd();
200                    }
201                    0x2: WarnUnimpl::strd(); // immediate
202                    0x3: decode HTRN {
203                        0xf: WarnUnimpl::ldrd(); // literal
204                        default: WarnUnimpl::ldrd(); // immediate
205                    }
206                }
207                0x4: decode HTOPCODE_4 {
208                    0x0: decode HTRN {
209                        0xd: WarnUnimpl::push();
210                        default: WarnUnimpl::stmdb(); // stmfd
211                    }
212                    0x1: WarnUnimpl::ldmdb(); // ldmea
213                }
214                0x5, 0x7: decode HTOPCODE_4 {
215                    0x0: WarnUnimpl::strd(); // immediate
216                    0x1: decode HTRN {
217                        0xf: WarnUnimpl::ldrd(); // literal
218                        default: WarnUnimpl::ldrd(); // immediate
219                    }
220                }
221            }
222            0x1: decode HTOPCODE_8_5 {
223                0x0: decode LTRD {
224                    0xf: decode HTS {
225                        0x1: WarnUnimpl::tst(); // register
226                    }
227                    default: WarnUnimpl::and(); // register
228                }
229                0x1: WarnUnimpl::bic(); // register
230                0x2: decode HTRN {
231                    0xf: WarnUnimpl::mov(); // register
232                    default: WarnUnimpl::orr(); // register
233                }
234                0x3: decode HTRN {
235                    0xf: WarnUnimpl::mvn(); // register
236                    default: WarnUnimpl::orn(); // register
237                }
238                0x4: decode LTRD {
239                    0xf: decode HTS {
240                        0x1: WarnUnimpl::teq(); // register
241                    }
242                    default: WarnUnimpl::eor(); // register
243                }
244                0x6: WarnUnimpl::pkh();
245                0x8: decode LTRD {
246                    0xf: decode HTS {
247                        0x1: WarnUnimpl::cmn(); // register
248                    }
249                    default: WarnUnimpl::add(); // register
250                }
251                0xa: WarnUnimpl::adc(); // register
252                0xb: WarnUnimpl::sbc(); // register
253                0xd: decode LTRD {
254                    0xf: decode HTS {
255                        0x1: WarnUnimpl::cmp(); // register
256                    }
257                    default: WarnUnimpl::sub(); // register
258                }
259                0xe: WarnUnimpl::rsb(); // register
260            }
261            default: decode HTOPCODE_9_8 {
262                0x2: decode LTOPCODE_4 {
263                    0x0: decode LTCOPROC {
264                        0xa, 0xb: decode OPCODE_23_20 {
265##include "vfp.isa"
266                        }
267                        default: WarnUnimpl::cdp(); // cdp2
268                    }
269                    0x1: decode LTCOPROC {
270                        0xa, 0xb: WarnUnimpl::Core_to_extension_transfer();
271                        default: decode HTOPCODE_4 {
272                            0x0: WarnUnimpl::mcr(); // mcr2
273                            0x1: WarnUnimpl::mrc(); // mrc2
274                        }
275                    }
276                }
277                0x3: WarnUnimpl::Advanced_SIMD();
278                default: decode LTCOPROC {
279                    0xa, 0xb: decode HTOPCODE_9_4 {
280                        0x00: WarnUnimpl::undefined();
281                        0x04: WarnUnimpl::mcrr(); // mcrr2
282                        0x05: WarnUnimpl::mrrc(); // mrrc2
283                        0x02, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10,
284                        0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e:
285                            WarnUnimpl::stc(); // stc2
286                        0x03, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11,
287                        0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f:
288                            decode HTRN {
289                                0xf: WarnUnimpl::ldc(); // ldc2 (literal)
290                                default: WarnUnimpl::ldc(); // ldc2 (immediate)
291                            }
292                    }
293                    default: decode HTOPCODE_9_5 {
294                        0x00: WarnUnimpl::undefined();
295                        0x02: WarnUnimpl::SIMD_VFP_64_bit_core_extension_transfer();
296                        0x01, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
297                        0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f:
298                            WarnUnimpl::Extension_register_load_store_instruction();
299                    }
300                }
301            }
302        }
303        0x2: decode LTOPCODE_15 {
304            0x0: decode HTOPCODE_9 {
305                0x0: decode HTOPCODE_8_5 {
306                    0x0: decode LTRD {
307                        0xf: decode HTS {
308                            0x1: DataModImmOp::tst({{
309                                resTemp = Rn & rotated_imm;
310                            }});
311                        }
312                        default: DataModImmOp::and({{
313                            Rs = resTemp = Rn & rotated_imm;
314                        }});
315                    }
316                    0x1: DataModImmOp::bic({{
317                        Rs = resTemp = Rn & ~rotated_imm;
318                    }});
319                    0x2: decode HTRN {
320                        0xf: DataModImmOp::mov({{
321                            Rs = resTemp = rotated_imm;
322                        }});
323                        default: DataModImmOp::orr({{
324                            Rs = resTemp = Rn | rotated_imm;
325                        }});
326                    }
327                    0x3: decode HTRN {
328                        0xf: DataModImmOp::mvn({{
329                            Rs = resTemp = ~rotated_imm;
330                        }});
331                        default: DataModImmOp::orn({{
332                            Rs = resTemp = Rn | ~rotated_imm;
333                        }});
334                    }
335                    0x4: decode LTRD {
336                        0xf: decode HTS {
337                            0x1: DataModImmOp::teq({{
338                                resTemp = Rn ^ rotated_imm;
339                            }});
340                        }
341                        default: DataModImmOp::eor({{
342                            Rs = resTemp = Rn ^ rotated_imm;
343                        }});
344                    }
345                    0x8: decode LTRD {
346                        0xf: decode HTS {
347                            0x1: DataModImmOp::cmn({{
348                                resTemp = Rn + rotated_imm;
349                            }}, add);
350                        }
351                        default: DataModImmOp::add({{
352                            Rs = resTemp = Rn + rotated_imm;
353                        }}, add);
354                    }
355                    0xa: DataModImmOp::adc({{
356                        Rs = resTemp = Rn + rotated_imm + CondCodes<29:>;
357                    }}, add);
358                    0xb: DataModImmOp::sbc({{
359                        Rs = resTemp = Rn - rotated_imm - !CondCodes<29:>;
360                    }}, sub);
361                    0xd: decode LTRD {
362                        0xf: decode HTS {
363                            0x1: DataModImmOp::cmp({{
364                                resTemp = Rn - rotated_imm;
365                            }}, sub);
366                        }
367                        default: DataModImmOp::sub({{
368                            Rs = resTemp = Rn - rotated_imm;
369                        }}, sub);
370                    }
371                    0xe: DataModImmOp::rsb({{
372                        Rs = resTemp = rotated_imm - Rn;
373                    }}, rsb);
374                }
375                0x1: WarnUnimpl::Data_processing_plain_binary_immediate();
376            }
377            0x1: WarnUnimpl::Branches_and_miscellaneous_control();
378        }
379        0x3: decode HTOPCODE_10_9 {
380            0x0: decode HTOPCODE_4 {
381                0x0: decode HTOPCODE_8 {
382                    0x0: Thumb32StoreSingle::thumb32StoreSingle();
383                    0x1: WarnUnimpl::Advanced_SIMD_or_structure_load_store();
384                }
385                0x1: decode HTOPCODE_6_5 {
386                    0x0: WarnUnimpl::Load_byte_memory_hints();
387                    0x1: WarnUnimpl::Load_halfword_memory_hints();
388                    0x2: Thumb32LoadWord::thumb32LoadWord();
389                    0x3: WarnUnimpl::undefined();
390                }
391            }
392            0x1: decode HTOPCODE_8_7 {
393                0x2: WarnUnimpl::Multiply_multiply_accumulate_and_absolute_difference();
394                0x3: WarnUnimpl::Long_multiply_long_multiply_accumulate_and_divide();
395                default: WarnUnimpl::Data_processing_register();
396            }
397            default: decode HTOPCODE_9_8 {
398                0x2: decode LTOPCODE_4 {
399                    0x0: decode LTCOPROC {
400                        0xa, 0xb: WarnUnimpl::VFP_Inst();
401                        default: WarnUnimpl::cdp(); // cdp2
402                    }
403                    0x1: decode LTCOPROC {
404                        0xa, 0xb: WarnUnimpl::Core_to_extension_transfer();
405                        default: decode HTOPCODE_4 {
406                            0x0: WarnUnimpl::mcr(); // mcr2
407                            0x1: WarnUnimpl::mrc(); // mrc2
408                        }
409                    }
410                }
411                0x3: WarnUnimpl::Advanced_SIMD();
412                default: decode LTCOPROC {
413                    0xa, 0xb: decode HTOPCODE_9_4 {
414                        0x00: WarnUnimpl::undefined();
415                        0x04: WarnUnimpl::mcrr(); // mcrr2
416                        0x05: WarnUnimpl::mrrc(); // mrrc2
417                        0x02, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10,
418                        0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e:
419                            WarnUnimpl::stc(); // stc2
420                        0x03, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11,
421                        0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f:
422                            decode HTRN {
423                                0xf: WarnUnimpl::ldc(); // ldc2 (literal)
424                                default: WarnUnimpl::ldc(); // ldc2 (immediate)
425                            }
426                    }
427                    default: decode HTOPCODE_9_5 {
428                        0x00: WarnUnimpl::undefined();
429                        0x02: WarnUnimpl::SIMD_VFP_64_bit_core_extension_transfer();
430                        0x01, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
431                        0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f:
432                            WarnUnimpl::Extension_register_load_store_instruction();
433                    }
434                }
435            }
436        }
437    }
438}
439