2 * Copyright (c) 2006-2007 The Regents of The University of Michigan
4 * Copyright 2017 Google Inc.
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.
30 #include "arch/sparc/insts/static_inst.hh"
35 const char *CondTestAbbrev
[] =
41 [LessOrEqualUnsigned
] = "leu",
48 [GreaterOrEqual
] = "ge",
49 [GreaterUnsigned
] = "gu",
52 [OverflowClear
] = "oc"
56 SparcStaticInst::printMnemonic(std::ostream
&os
, const char *mnemonic
)
58 ccprintf(os
, "\t%s ", mnemonic
);
62 SparcStaticInst::printRegArray(std::ostream
&os
, const RegId indexArray
[],
67 printReg(os
, indexArray
[0]);
68 for (int x
= 1; x
< num
; x
++) {
70 printReg(os
, indexArray
[x
]);
75 SparcStaticInst::advancePC(SparcISA::PCState
&pcState
) const
81 SparcStaticInst::printSrcReg(std::ostream
&os
, int reg
) const
83 if (_numSrcRegs
> reg
)
84 printReg(os
, _srcRegIdx
[reg
]);
88 SparcStaticInst::printDestReg(std::ostream
&os
, int reg
) const
90 if (_numDestRegs
> reg
)
91 printReg(os
, _destRegIdx
[reg
]);
95 SparcStaticInst::printReg(std::ostream
&os
, RegId reg
)
97 const int MaxGlobal
= 8;
98 const int MaxOutput
= 16;
99 const int MaxLocal
= 24;
100 const int MaxInput
= 32;
101 const int MaxMicroReg
= 40;
102 RegIndex reg_idx
= reg
.index();
103 if (reg
.isIntReg()) {
104 // If we used a register from the next or previous window,
105 // take out the offset.
106 while (reg_idx
>= MaxMicroReg
)
107 reg_idx
-= MaxMicroReg
;
108 if (reg_idx
== FramePointerReg
)
109 ccprintf(os
, "%%fp");
110 else if (reg_idx
== StackPointerReg
)
111 ccprintf(os
, "%%sp");
112 else if (reg_idx
< MaxGlobal
)
113 ccprintf(os
, "%%g%d", reg_idx
);
114 else if (reg_idx
< MaxOutput
)
115 ccprintf(os
, "%%o%d", reg_idx
- MaxGlobal
);
116 else if (reg_idx
< MaxLocal
)
117 ccprintf(os
, "%%l%d", reg_idx
- MaxOutput
);
118 else if (reg_idx
< MaxInput
)
119 ccprintf(os
, "%%i%d", reg_idx
- MaxLocal
);
120 else if (reg_idx
< MaxMicroReg
)
121 ccprintf(os
, "%%u%d", reg_idx
- MaxInput
);
122 // The fake int regs that are really control regs
124 switch (reg_idx
- MaxMicroReg
) {
129 ccprintf(os
, "%%ccr");
132 ccprintf(os
, "%%cansave");
135 ccprintf(os
, "%%canrestore");
138 ccprintf(os
, "%%cleanwin");
141 ccprintf(os
, "%%otherwin");
144 ccprintf(os
, "%%wstate");
148 } else if (reg
.isFloatReg()) {
149 ccprintf(os
, "%%f%d", reg_idx
);
153 ccprintf(os
, "%%asi");
156 ccprintf(os
, "%%fprs");
159 ccprintf(os
, "%%pcr");
162 ccprintf(os
, "%%pic");
165 ccprintf(os
, "%%gsr");
167 case MISCREG_SOFTINT
:
168 ccprintf(os
, "%%softint");
170 case MISCREG_SOFTINT_SET
:
171 ccprintf(os
, "%%softint_set");
173 case MISCREG_SOFTINT_CLR
:
174 ccprintf(os
, "%%softint_clr");
176 case MISCREG_TICK_CMPR
:
177 ccprintf(os
, "%%tick_cmpr");
180 ccprintf(os
, "%%stick");
182 case MISCREG_STICK_CMPR
:
183 ccprintf(os
, "%%stick_cmpr");
186 ccprintf(os
, "%%tpc");
189 ccprintf(os
, "%%tnpc");
192 ccprintf(os
, "%%tstate");
195 ccprintf(os
, "%%tt");
198 ccprintf(os
, "%%tick");
201 ccprintf(os
, "%%tba");
204 ccprintf(os
, "%%pstate");
207 ccprintf(os
, "%%tl");
210 ccprintf(os
, "%%pil");
213 ccprintf(os
, "%%cwp");
216 ccprintf(os
, "%%gl");
218 case MISCREG_HPSTATE
:
219 ccprintf(os
, "%%hpstate");
221 case MISCREG_HTSTATE
:
222 ccprintf(os
, "%%htstate");
225 ccprintf(os
, "%%hintp");
228 ccprintf(os
, "%%htba");
230 case MISCREG_HSTICK_CMPR
:
231 ccprintf(os
, "%%hstick_cmpr");
234 ccprintf(os
, "%%hver");
236 case MISCREG_STRAND_STS_REG
:
237 ccprintf(os
, "%%strand_sts_reg");
240 ccprintf(os
, "%%fsr");
243 ccprintf(os
, "%%ctrl%d", reg_idx
);
249 SparcStaticInst::generateDisassembly(
250 Addr pc
, const Loader::SymbolTable
*symtab
) const
252 std::stringstream ss
;
254 printMnemonic(ss
, mnemonic
);
256 // just print the first two source regs... if there's
257 // a third one, it's a read-modify-write dest (Rc),
260 printReg(ss
, _srcRegIdx
[0]);
261 if (_numSrcRegs
> 1) {
263 printReg(ss
, _srcRegIdx
[1]);
266 // just print the first dest... if there's a second one,
267 // it's generally implicit
268 if (_numDestRegs
> 0) {
271 printReg(ss
, _destRegIdx
[0]);
278 SparcStaticInst::passesFpCondition(uint32_t fcc
, uint32_t condition
)
294 case FUnorderedOrGreater
:
298 case FUnorderedOrLess
:
306 case FUnorderedOrEqual
:
308 case FGreaterOrEqual
:
310 case FUnorderedOrGreaterOrEqual
:
314 case FUnorderedOrLessOrEqual
:
319 panic("Tried testing condition nonexistant condition code %d", condition
);
323 SparcStaticInst::passesCondition(uint32_t codes
, uint32_t condition
)
325 BitUnion32(CondCodes
)
330 EndBitUnion(CondCodes
)
331 CondCodes condCodes
= codes
;
343 return !(condCodes
.z
| (condCodes
.n
^ condCodes
.v
));
345 return condCodes
.z
| (condCodes
.n
^ condCodes
.v
);
347 return !(condCodes
.n
^ condCodes
.v
);
349 return (condCodes
.n
^ condCodes
.v
);
350 case GreaterUnsigned
:
351 return !(condCodes
.c
| condCodes
.z
);
352 case LessOrEqualUnsigned
:
353 return (condCodes
.c
| condCodes
.z
);
367 panic("Tried testing condition nonexistant "
368 "condition code %d", condition
);