branch64.isa (12580:ad7057d38b98) branch64.isa (14172:bba55ff08279)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2011-2013, 2016,2018 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// Redistribution and use in source and binary forms, with or without
16// modification, are permitted provided that the following conditions are
17// met: redistributions of source code must retain the above copyright
18// notice, this list of conditions and the following disclaimer;
19// redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution;
22// neither the name of the copyright holders nor the names of its
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Authors: Gabe Black
39// Giacomo Gabrielli
40
41let {{
42
43 header_output = ""
44 decoder_output = ""
45 exec_output = ""
46
47 # B, BL
48 for (mnem, link) in (("b", False), ("bl", True)):
49 bCode = ('NPC = purifyTaggedAddr(RawPC + imm, xc->tcBase(), '
50 'currEL(xc->tcBase()));\n')
51 instFlags = ['IsDirectControl', 'IsUncondControl']
52 if (link):
53 bCode += 'XLR = RawPC + 4;\n'
54 instFlags += ['IsCall']
55
56 bIop = InstObjParams(mnem, mnem.capitalize() + "64",
57 "BranchImm64", bCode, instFlags)
58 header_output += BranchImm64Declare.subst(bIop)
59 decoder_output += BranchImm64Constructor.subst(bIop)
60 exec_output += BasicExecute.subst(bIop)
61
62 # BR, BLR
63 for (mnem, link) in (("br", False), ("blr", True)):
64 bCode = ('NPC = purifyTaggedAddr(XOp1, xc->tcBase(), '
65 'currEL(xc->tcBase()));\n')
66 instFlags = ['IsIndirectControl', 'IsUncondControl']
67 if (link):
68 bCode += 'XLR = RawPC + 4;\n'
69 instFlags += ['IsCall']
70
71 bIop = InstObjParams(mnem, mnem.capitalize() + "64",
72 "BranchReg64", bCode, instFlags)
73 header_output += BranchReg64Declare.subst(bIop)
74 decoder_output += BranchReg64Constructor.subst(bIop)
75 exec_output += BasicExecute.subst(bIop)
76
77 # B conditional
78 bCode = '''
79 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode))
80 NPC = purifyTaggedAddr(RawPC + imm, xc->tcBase(),
81 currEL(xc->tcBase()));
82 else
83 NPC = NPC;
84 '''
85 bIop = InstObjParams("b", "BCond64", "BranchImmCond64", bCode,
86 ['IsCondControl', 'IsDirectControl'])
87 header_output += BranchImmCond64Declare.subst(bIop)
88 decoder_output += BranchImmCond64Constructor.subst(bIop)
89 exec_output += BasicExecute.subst(bIop)
90
91 # RET
92 bCode = ('NPC = purifyTaggedAddr(XOp1, xc->tcBase(), '
93 'currEL(xc->tcBase()));\n')
94 instFlags = ['IsIndirectControl', 'IsUncondControl', 'IsReturn']
95
96 bIop = InstObjParams('ret', 'Ret64', "BranchRet64", bCode, instFlags)
97 header_output += BranchReg64Declare.subst(bIop)
98 decoder_output += BranchReg64Constructor.subst(bIop)
99 exec_output += BasicExecute.subst(bIop)
100
101 # ERET
102 bCode = '''Addr newPc;
103 CPSR cpsr = Cpsr;
104 CPSR spsr = Spsr;
105
1// -*- mode:c++ -*-
2
3// Copyright (c) 2011-2013, 2016,2018 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// Redistribution and use in source and binary forms, with or without
16// modification, are permitted provided that the following conditions are
17// met: redistributions of source code must retain the above copyright
18// notice, this list of conditions and the following disclaimer;
19// redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution;
22// neither the name of the copyright holders nor the names of its
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Authors: Gabe Black
39// Giacomo Gabrielli
40
41let {{
42
43 header_output = ""
44 decoder_output = ""
45 exec_output = ""
46
47 # B, BL
48 for (mnem, link) in (("b", False), ("bl", True)):
49 bCode = ('NPC = purifyTaggedAddr(RawPC + imm, xc->tcBase(), '
50 'currEL(xc->tcBase()));\n')
51 instFlags = ['IsDirectControl', 'IsUncondControl']
52 if (link):
53 bCode += 'XLR = RawPC + 4;\n'
54 instFlags += ['IsCall']
55
56 bIop = InstObjParams(mnem, mnem.capitalize() + "64",
57 "BranchImm64", bCode, instFlags)
58 header_output += BranchImm64Declare.subst(bIop)
59 decoder_output += BranchImm64Constructor.subst(bIop)
60 exec_output += BasicExecute.subst(bIop)
61
62 # BR, BLR
63 for (mnem, link) in (("br", False), ("blr", True)):
64 bCode = ('NPC = purifyTaggedAddr(XOp1, xc->tcBase(), '
65 'currEL(xc->tcBase()));\n')
66 instFlags = ['IsIndirectControl', 'IsUncondControl']
67 if (link):
68 bCode += 'XLR = RawPC + 4;\n'
69 instFlags += ['IsCall']
70
71 bIop = InstObjParams(mnem, mnem.capitalize() + "64",
72 "BranchReg64", bCode, instFlags)
73 header_output += BranchReg64Declare.subst(bIop)
74 decoder_output += BranchReg64Constructor.subst(bIop)
75 exec_output += BasicExecute.subst(bIop)
76
77 # B conditional
78 bCode = '''
79 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode))
80 NPC = purifyTaggedAddr(RawPC + imm, xc->tcBase(),
81 currEL(xc->tcBase()));
82 else
83 NPC = NPC;
84 '''
85 bIop = InstObjParams("b", "BCond64", "BranchImmCond64", bCode,
86 ['IsCondControl', 'IsDirectControl'])
87 header_output += BranchImmCond64Declare.subst(bIop)
88 decoder_output += BranchImmCond64Constructor.subst(bIop)
89 exec_output += BasicExecute.subst(bIop)
90
91 # RET
92 bCode = ('NPC = purifyTaggedAddr(XOp1, xc->tcBase(), '
93 'currEL(xc->tcBase()));\n')
94 instFlags = ['IsIndirectControl', 'IsUncondControl', 'IsReturn']
95
96 bIop = InstObjParams('ret', 'Ret64', "BranchRet64", bCode, instFlags)
97 header_output += BranchReg64Declare.subst(bIop)
98 decoder_output += BranchReg64Constructor.subst(bIop)
99 exec_output += BasicExecute.subst(bIop)
100
101 # ERET
102 bCode = '''Addr newPc;
103 CPSR cpsr = Cpsr;
104 CPSR spsr = Spsr;
105
106 ExceptionLevel curr_el = opModeToEL((OperatingMode) (uint8_t) cpsr.mode);
106 ExceptionLevel curr_el = currEL(cpsr);
107 switch (curr_el) {
108 case EL3:
109 newPc = xc->tcBase()->readMiscReg(MISCREG_ELR_EL3);
110 break;
111 case EL2:
112 newPc = xc->tcBase()->readMiscReg(MISCREG_ELR_EL2);
113 break;
114 case EL1:
115 newPc = xc->tcBase()->readMiscReg(MISCREG_ELR_EL1);
116 break;
117 default:
118 return std::make_shared<UndefinedInstruction>(machInst,
119 false,
120 mnemonic);
121 break;
122 }
123 if (spsr.width) {
124 // Exception return to AArch32.
125 // 32 most significant bits are ignored
126 newPc &= mask(32);
127
128 if (newPc & mask(2)) {
129 // Mask bits to avoid PC Alignment fault when returning
130 // to AArch32
131 if (spsr.t)
132 newPc = newPc & ~mask(1);
133 else
134 newPc = newPc & ~mask(2);
135 }
136 }
137
138 CPSR new_cpsr = getPSTATEFromPSR(xc->tcBase(), cpsr, spsr);
139
140 Cpsr = new_cpsr;
141 CondCodesNZ = new_cpsr.nz;
142 CondCodesC = new_cpsr.c;
143 CondCodesV = new_cpsr.v;
144
145 NextAArch64 = !new_cpsr.width;
146 NextItState = itState(new_cpsr);
147 NPC = purifyTaggedAddr(newPc, xc->tcBase(),
107 switch (curr_el) {
108 case EL3:
109 newPc = xc->tcBase()->readMiscReg(MISCREG_ELR_EL3);
110 break;
111 case EL2:
112 newPc = xc->tcBase()->readMiscReg(MISCREG_ELR_EL2);
113 break;
114 case EL1:
115 newPc = xc->tcBase()->readMiscReg(MISCREG_ELR_EL1);
116 break;
117 default:
118 return std::make_shared<UndefinedInstruction>(machInst,
119 false,
120 mnemonic);
121 break;
122 }
123 if (spsr.width) {
124 // Exception return to AArch32.
125 // 32 most significant bits are ignored
126 newPc &= mask(32);
127
128 if (newPc & mask(2)) {
129 // Mask bits to avoid PC Alignment fault when returning
130 // to AArch32
131 if (spsr.t)
132 newPc = newPc & ~mask(1);
133 else
134 newPc = newPc & ~mask(2);
135 }
136 }
137
138 CPSR new_cpsr = getPSTATEFromPSR(xc->tcBase(), cpsr, spsr);
139
140 Cpsr = new_cpsr;
141 CondCodesNZ = new_cpsr.nz;
142 CondCodesC = new_cpsr.c;
143 CondCodesV = new_cpsr.v;
144
145 NextAArch64 = !new_cpsr.width;
146 NextItState = itState(new_cpsr);
147 NPC = purifyTaggedAddr(newPc, xc->tcBase(),
148 opModeToEL((OperatingMode) (uint8_t) new_cpsr.mode));
148 currEL(new_cpsr));
149
150 LLSCLock = 0; // Clear exclusive monitor
151 SevMailbox = 1; //Set Event Register
152 '''
153 instFlags = ['IsSerializeAfter', 'IsNonSpeculative', 'IsSquashAfter']
154 bIop = InstObjParams('eret', 'Eret64', "BranchEret64", bCode, instFlags)
155 header_output += BasicDeclare.subst(bIop)
156 decoder_output += BasicConstructor64.subst(bIop)
157 exec_output += BasicExecute.subst(bIop)
158
159 # CBNZ, CBZ
160 for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")):
161 code = ('NPC = (Op164 %(test)s 0) ? '
162 'purifyTaggedAddr(RawPC + imm, xc->tcBase(), '
163 'currEL(xc->tcBase())) : NPC;\n')
164 code = code % {"test": test}
165 iop = InstObjParams(mnem, mnem.capitalize() + "64",
166 "BranchImmReg64", code,
167 ['IsCondControl', 'IsDirectControl'])
168 header_output += BranchImmReg64Declare.subst(iop)
169 decoder_output += BranchImmReg64Constructor.subst(iop)
170 exec_output += BasicExecute.subst(iop)
171
172 # TBNZ, TBZ
173 for (mnem, test) in (("tbz", "=="), ("tbnz", "!=")):
174 code = ('NPC = ((Op164 & imm1) %(test)s 0) ? '
175 'purifyTaggedAddr(RawPC + imm2, xc->tcBase(), '
176 'currEL(xc->tcBase())) : NPC;\n')
177 code = code % {"test": test}
178 iop = InstObjParams(mnem, mnem.capitalize() + "64",
179 "BranchImmImmReg64", code,
180 ['IsCondControl', 'IsDirectControl'])
181 header_output += BranchImmImmReg64Declare.subst(iop)
182 decoder_output += BranchImmImmReg64Constructor.subst(iop)
183 exec_output += BasicExecute.subst(iop)
184}};
149
150 LLSCLock = 0; // Clear exclusive monitor
151 SevMailbox = 1; //Set Event Register
152 '''
153 instFlags = ['IsSerializeAfter', 'IsNonSpeculative', 'IsSquashAfter']
154 bIop = InstObjParams('eret', 'Eret64', "BranchEret64", bCode, instFlags)
155 header_output += BasicDeclare.subst(bIop)
156 decoder_output += BasicConstructor64.subst(bIop)
157 exec_output += BasicExecute.subst(bIop)
158
159 # CBNZ, CBZ
160 for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")):
161 code = ('NPC = (Op164 %(test)s 0) ? '
162 'purifyTaggedAddr(RawPC + imm, xc->tcBase(), '
163 'currEL(xc->tcBase())) : NPC;\n')
164 code = code % {"test": test}
165 iop = InstObjParams(mnem, mnem.capitalize() + "64",
166 "BranchImmReg64", code,
167 ['IsCondControl', 'IsDirectControl'])
168 header_output += BranchImmReg64Declare.subst(iop)
169 decoder_output += BranchImmReg64Constructor.subst(iop)
170 exec_output += BasicExecute.subst(iop)
171
172 # TBNZ, TBZ
173 for (mnem, test) in (("tbz", "=="), ("tbnz", "!=")):
174 code = ('NPC = ((Op164 & imm1) %(test)s 0) ? '
175 'purifyTaggedAddr(RawPC + imm2, xc->tcBase(), '
176 'currEL(xc->tcBase())) : NPC;\n')
177 code = code % {"test": test}
178 iop = InstObjParams(mnem, mnem.capitalize() + "64",
179 "BranchImmImmReg64", code,
180 ['IsCondControl', 'IsDirectControl'])
181 header_output += BranchImmImmReg64Declare.subst(iop)
182 decoder_output += BranchImmImmReg64Constructor.subst(iop)
183 exec_output += BasicExecute.subst(iop)
184}};