Deleted Added
sdiff udiff text old ( 12234:78ece221f9f5 ) new ( 12288:f13eec2f5a17 )
full compact
1// Copyright (c) 2006-2007 The Regents of The University of Michigan
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met: redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer;
8// redistributions in binary form must reproduce the above copyright
9// notice, this list of conditions and the following disclaimer in the
10// documentation and/or other materials provided with the distribution;
11// neither the name of the copyright holders nor the names of its
12// contributors may be used to endorse or promote products derived from
13// this software without specific prior written permission.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26//
27// Authors: Gabe Black
28// Steve Reinhardt
29
30////////////////////////////////////////////////////////////////////
31//
32// Branch instructions
33//
34
35def template JumpExecute {{
36 Fault %(class_name)s::execute(ExecContext *xc,
37 Trace::InstRecord *traceData) const
38 {
39 // Attempt to execute the instruction
40 Fault fault = NoFault;
41
42 %(op_decl)s;
43 %(op_rd)s;
44
45 %(code)s;
46
47 if (fault == NoFault) {
48 // Write the resulting state to the execution context
49 %(op_wb)s;
50 }
51
52 return fault;
53 }
54}};
55
56def template BranchExecute {{
57 Fault
58 %(class_name)s::execute(ExecContext *xc,
59 Trace::InstRecord *traceData) const
60 {
61 // Attempt to execute the instruction
62 Fault fault = NoFault;
63
64 %(op_decl)s;
65 %(op_rd)s;
66
67 if (%(cond)s) {
68 %(code)s;
69 } else {
70 %(fail)s;
71 }
72
73 if (fault == NoFault) {
74 // Write the resulting state to the execution context
75 %(op_wb)s;
76 }
77
78 return fault;
79 }
80}};
81
82def template BranchDecode {{
83 if (A)
84 return new %(class_name)sAnnul("%(mnemonic)s,a", machInst);
85 else
86 return new %(class_name)s("%(mnemonic)s", machInst);
87}};
88
89// Primary format for branch instructions:
90def format Branch(code, *opt_flags) {{
91 code = 'NNPC = NNPC;\n' + code
92 (usesImm, code, immCode,
93 rString, iString) = splitOutImm(code)
94 iop = InstObjParams(name, Name, 'Branch', code, opt_flags)
95 header_output = BasicDeclare.subst(iop)
96 decoder_output = BasicConstructor.subst(iop)
97 exec_output = JumpExecute.subst(iop)
98 if usesImm:
99 imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString,
100 immCode, opt_flags)
101 header_output += BasicDeclare.subst(imm_iop)
102 decoder_output += BasicConstructor.subst(imm_iop)
103 exec_output += JumpExecute.subst(imm_iop)
104 decode_block = ROrImmDecode.subst(iop)
105 else:
106 decode_block = BasicDecode.subst(iop)
107}};
108
109let {{
110 def doBranch(name, Name, base, cond,
111 code, annul_code, fail, annul_fail, opt_flags):
112 #@todo: add flags and branchTarget() for DirectCntrl branches
113 # the o3 model can take advantage of this annotation if
114 # done correctly
115
116 iop = InstObjParams(name, Name, base,
117 {"code": code,
118 "fail": fail,
119 "cond": cond
120 },
121 opt_flags)
122 header_output = BasicDeclareWithMnemonic.subst(iop)
123 decoder_output = BasicConstructorWithMnemonic.subst(iop)
124 exec_output = BranchExecute.subst(iop)
125 if annul_code == "None":
126 decode_block = BasicDecodeWithMnemonic.subst(iop)
127 else:
128 decode_block = BranchDecode.subst(iop)
129
130 if annul_code != "None":
131 iop = InstObjParams(name + ',a', Name + 'Annul', base,
132 {"code": annul_code,
133 "fail": annul_fail,
134 "cond": cond
135 },
136 opt_flags)
137 header_output += BasicDeclareWithMnemonic.subst(iop)
138 decoder_output += BasicConstructorWithMnemonic.subst(iop)
139 exec_output += BranchExecute.subst(iop)
140 return (header_output, decoder_output, exec_output, decode_block)
141
142 def doCondBranch(name, Name, base, cond, code, opt_flags):
143 opt_flags += ('IsCondControl', )
144 return doBranch(name, Name, base, cond, code, code,
145 'NNPC = NNPC; NPC = NPC;\n',
146 'NNPC = NPC + 8; NPC = NPC + 4;\n',
147 opt_flags)
148
149 def doUncondBranch(name, Name, base, code, annul_code, opt_flags):
150 opt_flags += ('IsUncondControl', )
151 return doBranch(name, Name, base, "true", code, annul_code,
152 ";", ";", opt_flags)
153
154 default_branch_code = 'NNPC = PC + disp;\n'
155}};
156
157// Format for branch instructions with n bit displacements:
158def format BranchN(bits, code=default_branch_code,
159 test=None, annul_code=None, *opt_flags) {{
160 if code == "default_branch_code":
161 code = default_branch_code
162 if test != "None":
163 (header_output,
164 decoder_output,
165 exec_output,
166 decode_block) = doCondBranch(name, Name,
167 "BranchNBits<%d>" % bits, test, code, opt_flags)
168 else:
169 (header_output,
170 decoder_output,
171 exec_output,
172 decode_block) = doUncondBranch(name, Name,
173 "BranchNBits<%d>" % bits, code, annul_code, opt_flags)
174}};
175
176// Format for branch instructions with split displacements:
177def format BranchSplit(code=default_branch_code,
178 test=None, annul_code=None, *opt_flags) {{
179 if code == "default_branch_code":
180 code = default_branch_code
181 if test != "None":
182 (header_output,
183 decoder_output,
184 exec_output,
185 decode_block) = doCondBranch(name, Name,
186 "BranchSplit", test, code, opt_flags)
187 else:
188 (header_output,
189 decoder_output,
190 exec_output,
191 decode_block) = doUncondBranch(name, Name,
192 "BranchSplit", code, annul_code, opt_flags)
193}};
194