thumb.isa revision 7135:16f3c26a2923
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: Thumb16MemLit::thumb16MemLit();
93            default: Thumb16MemReg::thumb16MemReg();
94        }
95        0x3, 0x4: Thumb16MemImm::thumb16MemImm();
96        0x5: decode TOPCODE_12_11 {
97            0x0: WarnUnimpl::adr();
98            0x1: WarnUnimpl::add(); //sp, immediate
99            0x2: decode TOPCODE_10_8 {
100                0x0: decode TOPCODE_7 {
101                    0x0: WarnUnimpl::add(); //sp, immediate
102                    0x1: WarnUnimpl::sub(); //sp, immediate
103                }
104                0x1, 0x3: WarnUnimpl::cbz(); //cbnz too...
105                0x2: decode TOPCODE_7_6 {
106                    0x0: WarnUnimpl::sxth();
107                    0x1: WarnUnimpl::sxtb();
108                    0x2: WarnUnimpl::uxth();
109                    0x3: WarnUnimpl::uxtb();
110                }
111                0x4, 0x5: WarnUnimpl::pop();
112                0x6: decode TOPCODE_7_5 {
113                    0x2: WarnUnimpl::setend();
114                    0x3: WarnUnimpl::cps();
115                }
116            }
117            0x3: decode TOPCODE_10_8 {
118                0x1, 0x3: WarnUnimpl::cbz(); //cbnz too...
119                0x2: decode TOPCODE_7_6 {
120                    0x0: WarnUnimpl::rev();
121                    0x1: WarnUnimpl::rev16();
122                    0x3: WarnUnimpl::revsh();
123                }
124                0x4, 0x5: WarnUnimpl::pop();
125                0x6: WarnUnimpl::bkpt();
126                0x7: decode TOPCODE_3_0 {
127                    0x0: WarnUnimpl::it();
128                    default: decode TOPCODE_7_4 {
129                        0x0: WarnUnimpl::nop();
130                        0x1: WarnUnimpl::yield();
131                        0x2: WarnUnimpl::wfe();
132                        0x3: WarnUnimpl::wfi();
133                        0x4: WarnUnimpl::sev();
134                        default: WarnUnimpl::unallocated_hint();
135                    }
136                }
137            }
138        }
139        0x6: decode TOPCODE_12_11 {
140            0x0, 0x1: Thumb16MacroMem::thumb16MacroMem();
141            default: decode TOPCODE_11_8 {
142                0xe: WarnUnimpl::undefined(); // permanently undefined
143                0xf: WarnUnimpl::svc(); // formerly swi
144                default: WarnUnimpl::b(); // conditional
145            }
146        }
147        0x7: decode TOPCODE_12_11 {
148            0x0: WarnUnimpl::b(); // unconditional
149        }
150    }
151
152    // 32 bit thumb instructions.
153    1: decode HTOPCODE_12_11 {
154        0x1: decode HTOPCODE_10_9 {
155            0x0: decode HTOPCODE_8_6 {
156                0x0, 0x6: decode HTOPCODE_4 {
157                    0x0: WarnUnimpl::srs();
158                    0x1: WarnUnimpl::rfe();
159                }
160                0x1: decode HTOPCODE_5_4 {
161                    0x0: WarnUnimpl::strex();
162                    0x1: WarnUnimpl::ldrex();
163                    0x2: WarnUnimpl::strd(); // immediate
164                    0x3: decode HTRN {
165                        0xf: WarnUnimpl::ldrd(); // literal
166                        default: WarnUnimpl::ldrd(); // immediate
167                    }
168                }
169                0x2: decode HTOPCODE_4 {
170                    0x0: WarnUnimpl::stm(); // stmia, stmea
171                    0x1: decode HTRN {
172                        0xd: WarnUnimpl::pop();
173                        default: WarnUnimpl::ldm(); // ldmia, ldmfd
174                    }
175                }
176                0x3: decode HTOPCODE_5_4 {
177                    0x0: decode LTOPCODE_7_4 {
178                        0x4: WarnUnimpl::strexb();
179                        0x5: WarnUnimpl::strexh();
180                        0x7: WarnUnimpl::strexd();
181                    }
182                    0x1: decode LTOPCODE_7_4 {
183                        0x0: WarnUnimpl::tbb();
184                        0x1: WarnUnimpl::tbh();
185                        0x4: WarnUnimpl::ldrexb();
186                        0x5: WarnUnimpl::ldrexh();
187                        0x7: WarnUnimpl::ldrexd();
188                    }
189                    0x2: WarnUnimpl::strd(); // immediate
190                    0x3: decode HTRN {
191                        0xf: WarnUnimpl::ldrd(); // literal
192                        default: WarnUnimpl::ldrd(); // immediate
193                    }
194                }
195                0x4: decode HTOPCODE_4 {
196                    0x0: decode HTRN {
197                        0xd: WarnUnimpl::push();
198                        default: WarnUnimpl::stmdb(); // stmfd
199                    }
200                    0x1: WarnUnimpl::ldmdb(); // ldmea
201                }
202                0x5, 0x7: decode HTOPCODE_4 {
203                    0x0: WarnUnimpl::strd(); // immediate
204                    0x1: decode HTRN {
205                        0xf: WarnUnimpl::ldrd(); // literal
206                        default: WarnUnimpl::ldrd(); // immediate
207                    }
208                }
209            }
210            0x1: decode HTOPCODE_8_5 {
211                0x0: decode LTRD {
212                    0xf: decode HTS {
213                        0x1: WarnUnimpl::tst(); // register
214                    }
215                    default: WarnUnimpl::and(); // register
216                }
217                0x1: WarnUnimpl::bic(); // register
218                0x2: decode HTRN {
219                    0xf: WarnUnimpl::mov(); // register
220                    default: WarnUnimpl::orr(); // register
221                }
222                0x3: decode HTRN {
223                    0xf: WarnUnimpl::mvn(); // register
224                    default: WarnUnimpl::orn(); // register
225                }
226                0x4: decode LTRD {
227                    0xf: decode HTS {
228                        0x1: WarnUnimpl::teq(); // register
229                    }
230                    default: WarnUnimpl::eor(); // register
231                }
232                0x6: WarnUnimpl::pkh();
233                0x8: decode LTRD {
234                    0xf: decode HTS {
235                        0x1: WarnUnimpl::cmn(); // register
236                    }
237                    default: WarnUnimpl::add(); // register
238                }
239                0xa: WarnUnimpl::adc(); // register
240                0xb: WarnUnimpl::sbc(); // register
241                0xd: decode LTRD {
242                    0xf: decode HTS {
243                        0x1: WarnUnimpl::cmp(); // register
244                    }
245                    default: WarnUnimpl::sub(); // register
246                }
247                0xe: WarnUnimpl::rsb(); // register
248            }
249            default: decode HTOPCODE_9_8 {
250                0x2: decode LTOPCODE_4 {
251                    0x0: decode LTCOPROC {
252                        0xa, 0xb: decode OPCODE_23_20 {
253##include "vfp.isa"
254                        }
255                        default: WarnUnimpl::cdp(); // cdp2
256                    }
257                    0x1: decode LTCOPROC {
258                        0xa, 0xb: WarnUnimpl::Core_to_extension_transfer();
259                        default: decode HTOPCODE_4 {
260                            0x0: WarnUnimpl::mcr(); // mcr2
261                            0x1: WarnUnimpl::mrc(); // mrc2
262                        }
263                    }
264                }
265                0x3: WarnUnimpl::Advanced_SIMD();
266                default: decode LTCOPROC {
267                    0xa, 0xb: decode HTOPCODE_9_4 {
268                        0x00: WarnUnimpl::undefined();
269                        0x04: WarnUnimpl::mcrr(); // mcrr2
270                        0x05: WarnUnimpl::mrrc(); // mrrc2
271                        0x02, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10,
272                        0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e:
273                            WarnUnimpl::stc(); // stc2
274                        0x03, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11,
275                        0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f:
276                            decode HTRN {
277                                0xf: WarnUnimpl::ldc(); // ldc2 (literal)
278                                default: WarnUnimpl::ldc(); // ldc2 (immediate)
279                            }
280                    }
281                    default: decode HTOPCODE_9_5 {
282                        0x00: WarnUnimpl::undefined();
283                        0x02: WarnUnimpl::SIMD_VFP_64_bit_core_extension_transfer();
284                        0x01, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
285                        0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f:
286                            WarnUnimpl::Extension_register_load_store_instruction();
287                    }
288                }
289            }
290        }
291        0x2: decode LTOPCODE_15 {
292            0x0: decode HTOPCODE_9 {
293                0x0: decode HTOPCODE_8_5 {
294                    0x0: decode LTRD {
295                        0xf: decode HTS {
296                            0x1: DataModImmOp::tst({{
297                                resTemp = Rn & rotated_imm;
298                            }});
299                        }
300                        default: DataModImmOp::and({{
301                            Rs = resTemp = Rn & rotated_imm;
302                        }});
303                    }
304                    0x1: DataModImmOp::bic({{
305                        Rs = resTemp = Rn & ~rotated_imm;
306                    }});
307                    0x2: decode HTRN {
308                        0xf: DataModImmOp::mov({{
309                            Rs = resTemp = rotated_imm;
310                        }});
311                        default: DataModImmOp::orr({{
312                            Rs = resTemp = Rn | rotated_imm;
313                        }});
314                    }
315                    0x3: decode HTRN {
316                        0xf: DataModImmOp::mvn({{
317                            Rs = resTemp = ~rotated_imm;
318                        }});
319                        default: DataModImmOp::orn({{
320                            Rs = resTemp = Rn | ~rotated_imm;
321                        }});
322                    }
323                    0x4: decode LTRD {
324                        0xf: decode HTS {
325                            0x1: DataModImmOp::teq({{
326                                resTemp = Rn ^ rotated_imm;
327                            }});
328                        }
329                        default: DataModImmOp::eor({{
330                            Rs = resTemp = Rn ^ rotated_imm;
331                        }});
332                    }
333                    0x8: decode LTRD {
334                        0xf: decode HTS {
335                            0x1: DataModImmOp::cmn({{
336                                resTemp = Rn + rotated_imm;
337                            }}, add);
338                        }
339                        default: DataModImmOp::add({{
340                            Rs = resTemp = Rn + rotated_imm;
341                        }}, add);
342                    }
343                    0xa: DataModImmOp::adc({{
344                        Rs = resTemp = Rn + rotated_imm + CondCodes<29:>;
345                    }}, add);
346                    0xb: DataModImmOp::sbc({{
347                        Rs = resTemp = Rn - rotated_imm - !CondCodes<29:>;
348                    }}, sub);
349                    0xd: decode LTRD {
350                        0xf: decode HTS {
351                            0x1: DataModImmOp::cmp({{
352                                resTemp = Rn - rotated_imm;
353                            }}, sub);
354                        }
355                        default: DataModImmOp::sub({{
356                            Rs = resTemp = Rn - rotated_imm;
357                        }}, sub);
358                    }
359                    0xe: DataModImmOp::rsb({{
360                        Rs = resTemp = rotated_imm - Rn;
361                    }}, rsb);
362                }
363                0x1: WarnUnimpl::Data_processing_plain_binary_immediate();
364            }
365            0x1: WarnUnimpl::Branches_and_miscellaneous_control();
366        }
367        0x3: decode HTOPCODE_10_9 {
368            0x0: decode HTOPCODE_4 {
369                0x0: decode HTOPCODE_8 {
370                    0x0: Thumb32StoreSingle::thumb32StoreSingle();
371                    0x1: WarnUnimpl::Advanced_SIMD_or_structure_load_store();
372                }
373                0x1: decode HTOPCODE_6_5 {
374                    0x0: WarnUnimpl::Load_byte_memory_hints();
375                    0x1: WarnUnimpl::Load_halfword_memory_hints();
376                    0x2: Thumb32LoadWord::thumb32LoadWord();
377                    0x3: WarnUnimpl::undefined();
378                }
379            }
380            0x1: decode HTOPCODE_8_7 {
381                0x2: WarnUnimpl::Multiply_multiply_accumulate_and_absolute_difference();
382                0x3: WarnUnimpl::Long_multiply_long_multiply_accumulate_and_divide();
383                default: WarnUnimpl::Data_processing_register();
384            }
385            default: decode HTOPCODE_9_8 {
386                0x2: decode LTOPCODE_4 {
387                    0x0: decode LTCOPROC {
388                        0xa, 0xb: WarnUnimpl::VFP_Inst();
389                        default: WarnUnimpl::cdp(); // cdp2
390                    }
391                    0x1: decode LTCOPROC {
392                        0xa, 0xb: WarnUnimpl::Core_to_extension_transfer();
393                        default: decode HTOPCODE_4 {
394                            0x0: WarnUnimpl::mcr(); // mcr2
395                            0x1: WarnUnimpl::mrc(); // mrc2
396                        }
397                    }
398                }
399                0x3: WarnUnimpl::Advanced_SIMD();
400                default: decode LTCOPROC {
401                    0xa, 0xb: decode HTOPCODE_9_4 {
402                        0x00: WarnUnimpl::undefined();
403                        0x04: WarnUnimpl::mcrr(); // mcrr2
404                        0x05: WarnUnimpl::mrrc(); // mrrc2
405                        0x02, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10,
406                        0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e:
407                            WarnUnimpl::stc(); // stc2
408                        0x03, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x11,
409                        0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f:
410                            decode HTRN {
411                                0xf: WarnUnimpl::ldc(); // ldc2 (literal)
412                                default: WarnUnimpl::ldc(); // ldc2 (immediate)
413                            }
414                    }
415                    default: decode HTOPCODE_9_5 {
416                        0x00: WarnUnimpl::undefined();
417                        0x02: WarnUnimpl::SIMD_VFP_64_bit_core_extension_transfer();
418                        0x01, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
419                        0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f:
420                            WarnUnimpl::Extension_register_load_store_instruction();
421                    }
422                }
423            }
424        }
425    }
426}
427