branch.isa revision 7188
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) 2007-2008 The Florida State University
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: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Control transfer instructions
46//
47
48def format ArmBBlxImm() {{
49    decode_block = '''
50        if (machInst.condCode == 0xF) {
51            int32_t imm = (sext<26>(bits(machInst, 23, 0) << 2)) |
52                          (bits(machInst, 24) << 1);
53            return new BlxImm(machInst, imm);
54        } else {
55            return new B(machInst, sext<26>(bits(machInst, 23, 0) << 2),
56                         (ConditionCode)(uint32_t)machInst.condCode);
57        }
58    '''
59}};
60
61def format ArmBlBlxImm() {{
62    decode_block = '''
63        if (machInst.condCode == 0xF) {
64            int32_t imm = (sext<26>(bits(machInst, 23, 0) << 2)) |
65                          (bits(machInst, 24) << 1);
66            return new BlxImm(machInst, imm);
67        } else {
68            return new Bl(machInst, sext<26>(bits(machInst, 23, 0) << 2),
69                          (ConditionCode)(uint32_t)machInst.condCode);
70        }
71    '''
72}};
73
74def format ArmBx() {{
75    decode_block = '''
76        return new BxReg(machInst, (IntRegIndex)(uint32_t)bits(machInst, 3, 0),
77                         (ConditionCode)(uint32_t)machInst.condCode);
78    '''
79}};
80
81def format ArmBlxReg() {{
82    decode_block = '''
83        return new BlxReg(machInst, (IntRegIndex)(uint32_t)bits(machInst, 3, 0),
84                          (ConditionCode)(uint32_t)machInst.condCode);
85    '''
86}};
87
88def format Thumb16CondBranchAndSvc() {{
89    decode_block = '''
90        if (bits(machInst, 11, 9) != 0x7) {
91            return new B(machInst, sext<9>(bits(machInst, 7, 0) << 1),
92                         (ConditionCode)(uint32_t)bits(machInst, 11, 8));
93        } else if (bits(machInst, 8)) {
94            return new WarnUnimplemented("svc", machInst);
95        } else {
96            // This space will not be allocated in the future.
97            return new WarnUnimplemented("unimplemented", machInst);
98        }
99    '''
100}};
101
102def format Thumb16UncondBranch() {{
103    decode_block = '''
104        return new B(machInst, sext<12>(bits(machInst, 10, 0) << 1), COND_UC);
105    '''
106}};
107
108def format Thumb32BranchesAndMiscCtrl() {{
109    decode_block = '''
110    {
111        const uint32_t op = bits(machInst, 26, 20);
112        const uint32_t op1 = bits(machInst, 14, 12);
113        const uint32_t op2 = bits(machInst, 11, 8);
114        switch (op1 & 0x5) {
115          case 0x0:
116            if (op == 127) {
117                if (op1 & 0x2) {
118                    // Permanentl undefined.
119                    return new WarnUnimplemented("undefined", machInst);
120                } else {
121                    return new WarnUnimplemented("smc", machInst);
122                }
123            } else if ((op & 0x38) != 0x38) {
124                const uint32_t s = bits(machInst, 26);
125                const uint32_t j1 = bits(machInst, 13);
126                const uint32_t j2 = bits(machInst, 11);
127                const uint32_t imm6 = bits(machInst, 21, 16);
128                const uint32_t imm11 = bits(machInst, 10, 0);
129                const int32_t imm = sext<21>((s << 20) |
130                                             (j2 << 19) | (j1 << 18) |
131                                             (imm6 << 12) | (imm11 << 1));
132                return new B(machInst, imm,
133                             (ConditionCode)(uint32_t)bits(machInst, 25, 22));
134            } else {
135                switch (op) {
136                  case 0x38:
137                    if ((op2 & 0x3) == 0) {
138                        // Application level
139                        return new WarnUnimplemented("msr", machInst);
140                    }
141                    // Fall through on purpose...
142                  case 0x39:
143                    // System level
144                    return new WarnUnimplemented("msr", machInst);
145                  case 0x3a:
146                    {
147                        const uint32_t op1 = bits(machInst, 10, 8);
148                        const uint32_t op2 = bits(machInst, 7, 0);
149                        if (op1 != 0) {
150                            return new WarnUnimplemented("cps", machInst);
151                        } else if ((op2 & 0xf0) == 0xf0) {
152                            return new WarnUnimplemented("dbg", machInst);
153                        } else {
154                            switch (op2) {
155                              case 0x0:
156                                return new WarnUnimplemented("nop", machInst);
157                              case 0x1:
158                                return new WarnUnimplemented("yield", machInst);
159                              case 0x2:
160                                return new WarnUnimplemented("wfe", machInst);
161                              case 0x3:
162                                return new WarnUnimplemented("wfi", machInst);
163                              case 0x4:
164                                return new WarnUnimplemented("sev", machInst);
165                              default:
166                                break;
167                            }
168                        }
169                        break;
170                    }
171                  case 0x3b:
172                    {
173                        const uint32_t op = bits(machInst, 7, 4);
174                        switch (op) {
175                          case 0x0:
176                            return new WarnUnimplemented("leavex", machInst);
177                          case 0x1:
178                            return new WarnUnimplemented("enterx", machInst);
179                          case 0x2:
180                            return new WarnUnimplemented("clrex", machInst);
181                          case 0x4:
182                            return new WarnUnimplemented("dsb", machInst);
183                          case 0x5:
184                            return new WarnUnimplemented("dmb", machInst);
185                          case 0x6:
186                            return new WarnUnimplemented("isb", machInst);
187                          default:
188                            break;
189                        }
190                        break;
191                    }
192                  case 0x3c:
193                    return new WarnUnimplemented("bxj", machInst);
194                  case 0x3d:
195                    {
196                        const uint32_t imm32 = bits(machInst, 7, 0);
197                        return new SubsImmPclr(machInst, INTREG_PC, INTREG_LR,
198                                               imm32, false);
199                    }
200                  case 0x3e:
201                  case 0x3f:
202                    return new WarnUnimplemented("mrs", machInst);
203                }
204                break;
205            }
206          case 0x1:
207            {
208                const uint32_t s = bits(machInst, 26);
209                const uint32_t i1 = !(bits(machInst, 13) ^ s);
210                const uint32_t i2 = !(bits(machInst, 11) ^ s);
211                const uint32_t imm10 = bits(machInst, 25, 16);
212                const uint32_t imm11 = bits(machInst, 10, 0);
213                const int32_t imm = sext<25>((s << 24) |
214                                             (i1 << 23) | (i2 << 22) |
215                                             (imm10 << 12) | (imm11 << 1));
216                return new B(machInst, imm, COND_UC);
217            }
218          case 0x4:
219            {
220                const uint32_t s = bits(machInst, 26);
221                const uint32_t i1 = !(bits(machInst, 13) ^ s);
222                const uint32_t i2 = !(bits(machInst, 11) ^ s);
223                const uint32_t imm10h = bits(machInst, 25, 16);
224                const uint32_t imm10l = bits(machInst, 10, 1);
225                const int32_t imm = sext<25>((s << 24) |
226                                             (i1 << 23) | (i2 << 22) |
227                                             (imm10h << 12) | (imm10l << 2));
228                return new BlxImm(machInst, imm);
229            }
230          case 0x5:
231            {
232                const uint32_t s = bits(machInst, 26);
233                const uint32_t i1 = !(bits(machInst, 13) ^ s);
234                const uint32_t i2 = !(bits(machInst, 11) ^ s);
235                const uint32_t imm10 = bits(machInst, 25, 16);
236                const uint32_t imm11 = bits(machInst, 10, 0);
237                const int32_t imm = sext<25>((s << 24) |
238                                             (i1 << 23) | (i2 << 22) |
239                                             (imm10 << 12) | (imm11 << 1));
240                return new Bl(machInst, imm, COND_UC);
241            }
242          default:
243            break;
244        }
245        return new Unknown(machInst);
246    }
247    '''
248}};
249