branch.isa (7720:65d338a8dba4) branch.isa (7797:998b217dcae7)
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

--- 32 unchanged lines hidden (view full) ---

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 = '''
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

--- 32 unchanged lines hidden (view full) ---

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 ArmISA::PCState pc = PCS;
50 Addr curPc = pc.instPC();
51 pc.instNPC((uint32_t)(curPc + imm));
52 PCS = pc;
49 NPC = (uint32_t)(PC + imm);
53 '''
54 if (link):
55 bCode += '''
50 '''
51 if (link):
52 bCode += '''
56 if (pc.thumb())
57 LR = curPc | 1;
53 if (Thumb)
54 LR = PC | 1;
58 else
55 else
59 LR = curPc - 4;
56 LR = PC - 4;
60 '''
61
62 bIop = InstObjParams(mnem, mnem.capitalize(), "BranchImmCond",
63 {"code": bCode,
64 "predicate_test": predicateTest})
65 header_output += BranchImmCondDeclare.subst(bIop)
66 decoder_output += BranchImmCondConstructor.subst(bIop)
67 exec_output += PredOpExecute.subst(bIop)
68
69 # BX, BLX
70 blxCode = '''
57 '''
58
59 bIop = InstObjParams(mnem, mnem.capitalize(), "BranchImmCond",
60 {"code": bCode,
61 "predicate_test": predicateTest})
62 header_output += BranchImmCondDeclare.subst(bIop)
63 decoder_output += BranchImmCondConstructor.subst(bIop)
64 exec_output += PredOpExecute.subst(bIop)
65
66 # BX, BLX
67 blxCode = '''
71 ArmISA::PCState pc = PCS;
72 Addr curPc M5_VAR_USED = pc.instPC();
73 %(link)s
74 // Switch modes
75 %(branch)s
68 %(link)s
69 // Switch modes
70 %(branch)s
76 PCS = pc;
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()
85 if imm:
86 Name += "Imm"
87 # Since we're switching ISAs, the target ISA will be the opposite
71 '''
72
73 blxList = (("blx", True, True),
74 ("blx", False, True),
75 ("bx", False, False))
76
77 for (mnem, imm, link) in blxList:
78 Name = mnem.capitalize()
79 if imm:
80 Name += "Imm"
81 # Since we're switching ISAs, the target ISA will be the opposite
88 # of the current ISA. pc.thumb() is whether the target is ARM.
89 newPC = '(pc.thumb() ? (roundDown(curPc, 4) + imm) : (curPc + imm))'
82 # of the current ISA. Thumb is whether the target is ARM.
83 newPC = '(Thumb ? (roundDown(PC, 4) + imm) : (PC + imm))'
90 base = "BranchImmCond"
91 declare = BranchImmCondDeclare
92 constructor = BranchImmCondConstructor
93 else:
94 Name += "Reg"
95 newPC = 'Op1'
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
84 base = "BranchImmCond"
85 declare = BranchImmCondDeclare
86 constructor = BranchImmCondConstructor
87 else:
88 Name += "Reg"
89 newPC = 'Op1'
90 base = "BranchRegCond"
91 declare = BranchRegCondDeclare
92 constructor = BranchRegCondConstructor
93 if link and imm:
94 linkStr = '''
95 // The immediate version of the blx thumb instruction
96 // is 32 bits wide, but "next pc" doesn't reflect that
97 // so we don't want to substract 2 from it at this point
104 if (pc.thumb())
105 LR = curPc | 1;
98 if (Thumb)
99 LR = PC | 1;
106 else
100 else
107 LR = curPc - 4;
101 LR = PC - 4;
108 '''
109 elif link:
110 linkStr = '''
102 '''
103 elif link:
104 linkStr = '''
111 if (pc.thumb())
112 LR = (curPc - 2) | 1;
105 if (Thumb)
106 LR = (PC - 2) | 1;
113 else
107 else
114 LR = curPc - 4;
108 LR = PC - 4;
115 '''
116 else:
117 linkStr = ""
118
119 if imm and link: #blx with imm
120 branchStr = '''
109 '''
110 else:
111 linkStr = ""
112
113 if imm and link: #blx with imm
114 branchStr = '''
121 pc.nextThumb(!pc.thumb());
122 pc.instNPC(%(newPC)s);
115 NextThumb = !Thumb;
116 NPC = %(newPC)s;
123 '''
124 else:
117 '''
118 else:
125 branchStr = "pc.instIWNPC(%(newPC)s);"
119 branchStr = "IWNPC = %(newPC)s;"
126 branchStr = branchStr % { "newPC" : newPC }
127
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", "!=")):
120 branchStr = branchStr % { "newPC" : newPC }
121
122 code = blxCode % {"link": linkStr,
123 "newPC": newPC,
124 "branch": branchStr}
125 blxIop = InstObjParams(mnem, Name, base,
126 {"code": code,
127 "predicate_test": predicateTest})
128 header_output += declare.subst(blxIop)
129 decoder_output += constructor.subst(blxIop)
130 exec_output += PredOpExecute.subst(blxIop)
131
132 #Ignore BXJ for now
133
134 #CBNZ, CBZ. These are always unconditional as far as predicates
135 for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")):
142 code = '''
143 ArmISA::PCState pc = PCS;
144 Addr curPc = pc.instPC();
145 pc.instNPC((uint32_t)(curPc + imm));
146 PCS = pc;
147 '''
136 code = 'NPC = (uint32_t)(PC + imm);\n'
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 = '''
159 unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned |
160 ArmISA::TLB::AlignHalfWord |
161 ArmISA::TLB::MustBeOne;
162 EA = Op1 + Op2 * 2
163 '''
137 predTest = "Op1 %(test)s 0" % {"test": test}
138 iop = InstObjParams(mnem, mnem.capitalize(), "BranchImmReg",
139 {"code": code, "predicate_test": predTest})
140 header_output += BranchImmRegDeclare.subst(iop)
141 decoder_output += BranchImmRegConstructor.subst(iop)
142 exec_output += PredOpExecute.subst(iop)
143
144 #TBB, TBH
145 for isTbh in (0, 1):
146 if isTbh:
147 eaCode = '''
148 unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned |
149 ArmISA::TLB::AlignHalfWord |
150 ArmISA::TLB::MustBeOne;
151 EA = Op1 + Op2 * 2
152 '''
164 accCode = '''
165 ArmISA::PCState pc = PCS;
166 pc.instNPC(pc.instPC() + 2 * (Mem.uh));
167 PCS = pc;
168 '''
153 accCode = 'NPC = PC + 2 * (Mem.uh);\n'
169 mnem = "tbh"
170 else:
171 eaCode = '''
172 unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned |
173 ArmISA::TLB::AlignByte |
174 ArmISA::TLB::MustBeOne;
175 EA = Op1 + Op2
176 '''
154 mnem = "tbh"
155 else:
156 eaCode = '''
157 unsigned memAccessFlags = ArmISA::TLB::AllowUnaligned |
158 ArmISA::TLB::AlignByte |
159 ArmISA::TLB::MustBeOne;
160 EA = Op1 + Op2
161 '''
177 accCode = '''
178 ArmISA::PCState pc = PCS;
179 pc.instNPC(pc.instPC() + 2 * (Mem.ub));
180 PCS = pc;
181 '''
162 accCode = 'NPC = PC + 2 * (Mem.ub)'
182 mnem = "tbb"
183 iop = InstObjParams(mnem, mnem.capitalize(), "BranchRegReg",
184 {'ea_code': eaCode,
185 'memacc_code': accCode,
186 'predicate_test': predicateTest})
187 header_output += BranchTableDeclare.subst(iop)
188 decoder_output += BranchRegRegConstructor.subst(iop)
189 exec_output += LoadExecute.subst(iop) + \
190 LoadInitiateAcc.subst(iop) + \
191 LoadCompleteAcc.subst(iop)
192}};
163 mnem = "tbb"
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}};