branch.isa (7151:672a20bbd4ff) branch.isa (7282:547cddd4e837)
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// 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
40let {{
41
42 header_output = ""
43 decoder_output = ""
44 exec_output = ""
45
46 # B, BL
47 for (mnem, link) in (("b", False), ("bl", True)):
48 bCode = '''
49 Addr PC = readPC(xc);
50 NPC = ((PC + imm) & mask(32)) | (PC & ~mask(32));
51 '''
52 if (link):
53 bCode += '''
54 Addr tBit = PC & (ULL(1) << PcTBitShift);
55 if (!tBit)
56 LR = PC - 4;
57 else
58 LR = PC | 1;
59 '''
60
61 bIop = InstObjParams(mnem, mnem.capitalize(), "BranchImmCond",
62 {"code": bCode,
63 "predicate_test": predicateTest})
64 header_output += BranchImmCondDeclare.subst(bIop)
65 decoder_output += BranchImmCondConstructor.subst(bIop)
66 exec_output += PredOpExecute.subst(bIop)
67
68 # BX, BLX
69 blxCode = '''
70 Addr PC = readPC(xc);
71 Addr tBit = PC & (ULL(1) << PcTBitShift);
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// 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
40let {{
41
42 header_output = ""
43 decoder_output = ""
44 exec_output = ""
45
46 # B, BL
47 for (mnem, link) in (("b", False), ("bl", True)):
48 bCode = '''
49 Addr PC = readPC(xc);
50 NPC = ((PC + imm) & mask(32)) | (PC & ~mask(32));
51 '''
52 if (link):
53 bCode += '''
54 Addr tBit = PC & (ULL(1) << PcTBitShift);
55 if (!tBit)
56 LR = PC - 4;
57 else
58 LR = PC | 1;
59 '''
60
61 bIop = InstObjParams(mnem, mnem.capitalize(), "BranchImmCond",
62 {"code": bCode,
63 "predicate_test": predicateTest})
64 header_output += BranchImmCondDeclare.subst(bIop)
65 decoder_output += BranchImmCondConstructor.subst(bIop)
66 exec_output += PredOpExecute.subst(bIop)
67
68 # BX, BLX
69 blxCode = '''
70 Addr PC = readPC(xc);
71 Addr tBit = PC & (ULL(1) << PcTBitShift);
72 // Other than the assert below, jBit isn't used.
73#if !defined(NDEBUG)
74 Addr jBit = PC & (ULL(1) << PcJBitShift);
75#endif
76 // X isn't permitted in ThumbEE mode. We shouldn't be in jazzelle mode?
77 assert(!jBit);
78 bool arm = !tBit;
79 arm = arm; // In case it's not used otherwise.
72 bool arm = !tBit;
73 arm = arm; // In case it's not used otherwise.
80 Addr tempPc = ((%(newPC)s) & mask(32)) | (PC & ~mask(32));
81 %(link)s
82 // Switch modes
83 %(branch)s
84 '''
85
86 blxList = (("blx", True, True),
87 ("blx", False, True),
88 ("bx", False, False))
89
90 for (mnem, imm, link) in blxList:
91 Name = mnem.capitalize()
74 %(link)s
75 // Switch modes
76 %(branch)s
77 '''
78
79 blxList = (("blx", True, True),
80 ("blx", False, True),
81 ("bx", False, False))
82
83 for (mnem, imm, link) in blxList:
84 Name = mnem.capitalize()
92 if imm and link: #blx with imm
93 branchStr = "FNPC = tempPc ^ (ULL(1) << PcTBitShift);"
94 else:
95 branchStr = "IWNPC = tempPc ^ (ULL(1) << PcTBitShift);"
96
97 if imm:
98 Name += "Imm"
99 # Since we're switching ISAs, the target ISA will be the opposite
100 # of the current ISA. !arm is whether the target is ARM.
101 newPC = '(!arm ? (roundDown(PC, 4) + imm) : (PC + imm))'
102 base = "BranchImm"
103 declare = BranchImmDeclare
104 constructor = BranchImmConstructor
105 else:
106 Name += "Reg"
85 if imm:
86 Name += "Imm"
87 # Since we're switching ISAs, the target ISA will be the opposite
88 # of the current ISA. !arm is whether the target is ARM.
89 newPC = '(!arm ? (roundDown(PC, 4) + imm) : (PC + imm))'
90 base = "BranchImm"
91 declare = BranchImmDeclare
92 constructor = BranchImmConstructor
93 else:
94 Name += "Reg"
107 newPC = '(PC & PcModeMask) | Op1'
95 newPC = 'Op1'
108 base = "BranchRegCond"
109 declare = BranchRegCondDeclare
110 constructor = BranchRegCondConstructor
111 if link and imm:
112 linkStr = '''
113 // The immediate version of the blx thumb instruction
114 // is 32 bits wide, but "next pc" doesn't reflect that
115 // so we don't want to substract 2 from it at this point
116 if (arm)
117 LR = PC - 4;
118 else
119 LR = PC | 1;
120 '''
121 elif link:
122 linkStr = '''
123 if (arm)
124 LR = PC - 4;
125 else
126 LR = (PC - 2) | 1;
127 '''
128 else:
129 linkStr = ""
96 base = "BranchRegCond"
97 declare = BranchRegCondDeclare
98 constructor = BranchRegCondConstructor
99 if link and imm:
100 linkStr = '''
101 // The immediate version of the blx thumb instruction
102 // is 32 bits wide, but "next pc" doesn't reflect that
103 // so we don't want to substract 2 from it at this point
104 if (arm)
105 LR = PC - 4;
106 else
107 LR = PC | 1;
108 '''
109 elif link:
110 linkStr = '''
111 if (arm)
112 LR = PC - 4;
113 else
114 LR = (PC - 2) | 1;
115 '''
116 else:
117 linkStr = ""
118
119 if imm and link: #blx with imm
120 branchStr = '''
121 Addr tempPc = ((%(newPC)s) & mask(32)) | (PC & ~mask(32));
122 FNPC = tempPc ^ (ULL(1) << PcTBitShift);
123 '''
124 else:
125 branchStr = "IWNPC = %(newPC)s;"
126 branchStr = branchStr % { "newPC" : newPC }
127
130 code = blxCode % {"link": linkStr,
131 "newPC": newPC,
132 "branch": branchStr}
133 blxIop = InstObjParams(mnem, Name, base,
134 {"code": code,
135 "predicate_test": predicateTest})
136 header_output += declare.subst(blxIop)
137 decoder_output += constructor.subst(blxIop)
138 exec_output += PredOpExecute.subst(blxIop)
139
140 #Ignore BXJ for now
141
142 #CBNZ, CBZ. These are always unconditional as far as predicates
143 for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")):
144 code = '''
145 Addr PC = readPC(xc);
146 NPC = ((PC + imm) & mask(32)) | (PC & ~mask(32));
147 '''
148 predTest = "Op1 %(test)s 0" % {"test": test}
149 iop = InstObjParams(mnem, mnem.capitalize(), "BranchImmReg",
150 {"code": code, "predicate_test": predTest})
151 header_output += BranchImmRegDeclare.subst(iop)
152 decoder_output += BranchImmRegConstructor.subst(iop)
153 exec_output += PredOpExecute.subst(iop)
154
155 #TBB, TBH
156 for isTbh in (0, 1):
157 if isTbh:
158 eaCode = "EA = Op1 + Op2 * 2"
159 accCode = "NPC = readPC(xc) + 2 * (Mem.uh);"
160 mnem = "tbh"
161 else:
162 eaCode = "EA = Op1 + Op2"
163 accCode = "NPC = readPC(xc) + 2 * (Mem.ub);"
164 mnem = "tbb"
165 eaCode = "unsigned memAccessFlags = 0;\n" + eaCode
166 iop = InstObjParams(mnem, mnem.capitalize(), "BranchRegReg",
167 {'ea_code': eaCode,
168 'memacc_code': accCode,
169 'predicate_test': predicateTest})
170 header_output += BranchTableDeclare.subst(iop)
171 decoder_output += BranchRegRegConstructor.subst(iop)
172 exec_output += LoadExecute.subst(iop) + \
173 LoadInitiateAcc.subst(iop) + \
174 LoadCompleteAcc.subst(iop)
175}};
128 code = blxCode % {"link": linkStr,
129 "newPC": newPC,
130 "branch": branchStr}
131 blxIop = InstObjParams(mnem, Name, base,
132 {"code": code,
133 "predicate_test": predicateTest})
134 header_output += declare.subst(blxIop)
135 decoder_output += constructor.subst(blxIop)
136 exec_output += PredOpExecute.subst(blxIop)
137
138 #Ignore BXJ for now
139
140 #CBNZ, CBZ. These are always unconditional as far as predicates
141 for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")):
142 code = '''
143 Addr PC = readPC(xc);
144 NPC = ((PC + imm) & mask(32)) | (PC & ~mask(32));
145 '''
146 predTest = "Op1 %(test)s 0" % {"test": test}
147 iop = InstObjParams(mnem, mnem.capitalize(), "BranchImmReg",
148 {"code": code, "predicate_test": predTest})
149 header_output += BranchImmRegDeclare.subst(iop)
150 decoder_output += BranchImmRegConstructor.subst(iop)
151 exec_output += PredOpExecute.subst(iop)
152
153 #TBB, TBH
154 for isTbh in (0, 1):
155 if isTbh:
156 eaCode = "EA = Op1 + Op2 * 2"
157 accCode = "NPC = readPC(xc) + 2 * (Mem.uh);"
158 mnem = "tbh"
159 else:
160 eaCode = "EA = Op1 + Op2"
161 accCode = "NPC = readPC(xc) + 2 * (Mem.ub);"
162 mnem = "tbb"
163 eaCode = "unsigned memAccessFlags = 0;\n" + eaCode
164 iop = InstObjParams(mnem, mnem.capitalize(), "BranchRegReg",
165 {'ea_code': eaCode,
166 'memacc_code': accCode,
167 'predicate_test': predicateTest})
168 header_output += BranchTableDeclare.subst(iop)
169 decoder_output += BranchRegRegConstructor.subst(iop)
170 exec_output += LoadExecute.subst(iop) + \
171 LoadInitiateAcc.subst(iop) + \
172 LoadCompleteAcc.subst(iop)
173}};