3 // Copyright (c) 2007 MIPS Technologies, Inc.
4 // All rights reserved.
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met: redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer;
10 // redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution;
13 // neither the name of the copyright holders nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 ////////////////////////////////////////////////////////////////////
31 // Integer operate instructions
37 * Base class for integer operations.
39 class IntOp : public MipsStaticInst
42 using MipsStaticInst::MipsStaticInst;
44 std::string generateDisassembly(
45 Addr pc, const Loader::SymbolTable *symtab) const override;
49 class HiLoOp: public IntOp
54 std::string generateDisassembly(
55 Addr pc, const Loader::SymbolTable *symtab) const override;
58 class HiLoRsSelOp: public HiLoOp
63 std::string generateDisassembly(
64 Addr pc, const Loader::SymbolTable *symtab) const override;
67 class HiLoRdSelOp: public HiLoOp
72 std::string generateDisassembly(
73 Addr pc, const Loader::SymbolTable *symtab) const override;
76 class HiLoRdSelValOp: public HiLoOp
81 std::string generateDisassembly(
82 Addr pc, const Loader::SymbolTable *symtab) const override;
85 class IntImmOp : public MipsStaticInst
92 IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
93 MipsStaticInst(mnem, _machInst, __opClass), imm(INTIMM),
94 sextImm(INTIMM), zextImm(0x0000FFFF & INTIMM)
96 // If Bit 15 is 1 then sign extend.
97 int32_t temp = sextImm & 0x00008000;
98 if (temp > 0 && strcmp(mnemonic,"lui") != 0) {
99 sextImm |= 0xFFFF0000;
103 std::string generateDisassembly(
104 Addr pc, const Loader::SymbolTable *symtab) const override;
109 // HiLo instruction class execute method template.
110 def template HiLoExecute {{
112 %(class_name)s::execute(
113 ExecContext *xc, Trace::InstRecord *traceData) const
115 Fault fault = NoFault;
122 if(fault == NoFault) {
129 // HiLoRsSel instruction class execute method template.
130 def template HiLoRsSelExecute {{
132 %(class_name)s::execute(
133 ExecContext *xc, Trace::InstRecord *traceData) const
135 Fault fault = NoFault;
139 if (ACSRC > 0 && !isDspEnabled(xc)) {
140 fault = std::make_shared<DspStateDisabledFault>();
146 if (fault == NoFault) {
153 // HiLoRdSel instruction class execute method template.
154 def template HiLoRdSelExecute {{
156 %(class_name)s::execute(
157 ExecContext *xc, Trace::InstRecord *traceData) const
159 Fault fault = NoFault;
163 if (ACDST > 0 && !isDspEnabled(xc)) {
164 fault = std::make_shared<DspStateDisabledFault>();
170 if (fault == NoFault) {
177 //Outputs to decoder.cc
180 IntOp::generateDisassembly(
181 Addr pc, const Loader::SymbolTable *symtab) const
183 std::stringstream ss;
185 ccprintf(ss, "%-10s ", mnemonic);
187 // just print the first dest... if there's a second one,
188 // it's generally implicit
189 if (_numDestRegs > 0) {
190 printReg(ss, _destRegIdx[0]);
194 // just print the first two source regs... if there's
195 // a third one, it's a read-modify-write dest (Rc),
197 if (_numSrcRegs > 0) {
198 printReg(ss, _srcRegIdx[0]);
201 if (_numSrcRegs > 1) {
203 printReg(ss, _srcRegIdx[1]);
210 HiLoOp::generateDisassembly(
211 Addr pc, const Loader::SymbolTable *symtab) const
213 std::stringstream ss;
215 ccprintf(ss, "%-10s ", mnemonic);
217 // Destination Registers are implicit for HI/LO ops
218 if (_numSrcRegs > 0) {
219 printReg(ss, _srcRegIdx[0]);
222 if (_numSrcRegs > 1) {
224 printReg(ss, _srcRegIdx[1]);
231 HiLoRsSelOp::generateDisassembly(
232 Addr pc, const Loader::SymbolTable *symtab) const
234 std::stringstream ss;
236 ccprintf(ss, "%-10s ", mnemonic);
238 if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) {
239 printReg(ss, _destRegIdx[0]);
240 } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) {
241 printReg(ss, _srcRegIdx[0]);
248 HiLoRdSelOp::generateDisassembly(
249 Addr pc, const Loader::SymbolTable *symtab) const
251 std::stringstream ss;
253 ccprintf(ss, "%-10s ", mnemonic);
255 if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) {
256 printReg(ss, _destRegIdx[0]);
257 } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) {
258 printReg(ss, _srcRegIdx[0]);
265 HiLoRdSelValOp::generateDisassembly(
266 Addr pc, const Loader::SymbolTable *symtab) const
268 std::stringstream ss;
270 ccprintf(ss, "%-10s ", mnemonic);
272 if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) {
273 printReg(ss, _destRegIdx[0]);
274 } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) {
275 printReg(ss, _srcRegIdx[0]);
282 IntImmOp::generateDisassembly(
283 Addr pc, const Loader::SymbolTable *symtab) const
285 std::stringstream ss;
287 ccprintf(ss, "%-10s ", mnemonic);
289 if (_numDestRegs > 0) {
290 printReg(ss, _destRegIdx[0]);
295 if (_numSrcRegs > 0) {
296 printReg(ss, _srcRegIdx[0]);
300 if(strcmp(mnemonic,"lui") == 0)
301 ccprintf(ss, "0x%x ", sextImm);
310 def format IntOp(code, *opt_flags) {{
311 iop = InstObjParams(name, Name, 'IntOp', code, opt_flags)
312 header_output = BasicDeclare.subst(iop)
313 decoder_output = BasicConstructor.subst(iop)
314 decode_block = RegNopCheckDecode.subst(iop)
315 exec_output = BasicExecute.subst(iop)
318 def format IntImmOp(code, *opt_flags) {{
319 iop = InstObjParams(name, Name, 'IntImmOp', code, opt_flags)
320 header_output = BasicDeclare.subst(iop)
321 decoder_output = BasicConstructor.subst(iop)
322 decode_block = ImmNopCheckDecode.subst(iop)
323 exec_output = BasicExecute.subst(iop)
326 def format HiLoRsSelOp(code, *opt_flags) {{
327 iop = InstObjParams(name, Name, 'HiLoRsSelOp', code, opt_flags)
328 header_output = BasicDeclare.subst(iop)
329 decoder_output = BasicConstructor.subst(iop)
330 decode_block = BasicDecode.subst(iop)
331 exec_output = HiLoRsSelExecute.subst(iop)
334 def format HiLoRdSelOp(code, *opt_flags) {{
335 iop = InstObjParams(name, Name, 'HiLoRdSelOp', code, opt_flags)
336 header_output = BasicDeclare.subst(iop)
337 decoder_output = BasicConstructor.subst(iop)
338 decode_block = BasicDecode.subst(iop)
339 exec_output = HiLoRdSelExecute.subst(iop)
342 def format HiLoRdSelValOp(code, *opt_flags) {{
345 code = 'int64_t ' + code
347 code = 'uint64_t ' + code
349 code += 'HI_RD_SEL = val<63:32>;\n'
350 code += 'LO_RD_SEL = val<31:0>;\n'
352 iop = InstObjParams(name, Name, 'HiLoRdSelOp', code, opt_flags)
353 header_output = BasicDeclare.subst(iop)
354 decoder_output = BasicConstructor.subst(iop)
355 decode_block = BasicDecode.subst(iop)
356 exec_output = HiLoRdSelExecute.subst(iop)
359 def format HiLoOp(code, *opt_flags) {{
360 iop = InstObjParams(name, Name, 'HiLoOp', code, opt_flags)
361 header_output = BasicDeclare.subst(iop)
362 decoder_output = BasicConstructor.subst(iop)
363 decode_block = BasicDecode.subst(iop)
364 exec_output = HiLoExecute.subst(iop)