1 // Copyright (c) 2006 The Regents of The University of Michigan
2 // All rights reserved.
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.
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.
31 ////////////////////////////////////////////////////////////////////
33 // Base class for sparc instructions, and some support functions
61 LessOrEqualUnsigned=0x4,
70 extern char * CondTestAbbrev[];
73 * Base class for all SPARC static instructions.
75 class SparcStaticInst : public StaticInst
79 SparcStaticInst(const char *mnem,
80 ExtMachInst _machInst, OpClass __opClass)
81 : StaticInst(mnem, _machInst, __opClass)
85 std::string generateDisassembly(Addr pc,
86 const SymbolTable *symtab) const;
88 void printReg(std::ostream &os, int reg) const;
89 void printSrcReg(std::ostream &os, int reg) const;
90 void printDestReg(std::ostream &os, int reg) const;
92 void printRegArray(std::ostream &os,
93 const RegIndex indexArray[], int num) const;
96 bool passesCondition(uint32_t codes, uint32_t condition);
98 inline int64_t sign_ext(uint64_t data, int origWidth)
100 int shiftAmount = 64 - origWidth;
101 return (((int64_t)data) << shiftAmount) >> shiftAmount;
107 char * CondTestAbbrev[] =
111 "le", //Less or Equal
113 "leu", //Less or Equal Unsigned
120 "ge", //Greater or Equal
121 "gu", //Greater Unsigned
124 "oc" //Overflow Clear
128 def template ROrImmDecode {{
130 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
131 : (SparcStaticInst *)(new %(class_name)s(machInst)));
136 def splitOutImm(code):
137 matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?')
138 rOrImmMatch = matcher.search(code)
139 if (rOrImmMatch == None):
140 return (False, code, '', '', '')
141 rString = rOrImmMatch.group("rNum")
142 if (rOrImmMatch.group("typeQual") != None):
143 rString += rOrImmMatch.group("typeQual")
144 iString = rOrImmMatch.group("iNum")
146 code = matcher.sub('Rs' + rString, orig_code)
147 imm_code = matcher.sub('imm', orig_code)
148 return (True, code, imm_code, rString, iString)
153 inline void printMnemonic(std::ostream &os, const char * mnemonic)
155 ccprintf(os, "\t%s ", mnemonic);
158 void SparcStaticInst::printRegArray(std::ostream &os,
159 const RegIndex indexArray[], int num) const
163 printReg(os, indexArray[0]);
164 for(int x = 1; x < num; x++)
167 printReg(os, indexArray[x]);
172 SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
174 if(_numSrcRegs > reg)
175 printReg(os, _srcRegIdx[reg]);
179 SparcStaticInst::printDestReg(std::ostream &os, int reg) const
181 if(_numDestRegs > reg)
182 printReg(os, _destRegIdx[reg]);
186 SparcStaticInst::printReg(std::ostream &os, int reg) const
188 const int MaxGlobal = 8;
189 const int MaxOutput = 16;
190 const int MaxLocal = 24;
191 const int MaxInput = 32;
192 const int MaxMicroReg = 33;
193 if (reg == FramePointerReg)
194 ccprintf(os, "%%fp");
195 else if (reg == StackPointerReg)
196 ccprintf(os, "%%sp");
197 else if(reg < MaxGlobal)
198 ccprintf(os, "%%g%d", reg);
199 else if(reg < MaxOutput)
200 ccprintf(os, "%%o%d", reg - MaxGlobal);
201 else if(reg < MaxLocal)
202 ccprintf(os, "%%l%d", reg - MaxOutput);
203 else if(reg < MaxInput)
204 ccprintf(os, "%%i%d", reg - MaxLocal);
205 else if(reg < MaxMicroReg)
206 ccprintf(os, "%%u%d", reg - MaxInput);
208 ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
212 std::string SparcStaticInst::generateDisassembly(Addr pc,
213 const SymbolTable *symtab) const
215 std::stringstream ss;
217 printMnemonic(ss, mnemonic);
219 // just print the first two source regs... if there's
220 // a third one, it's a read-modify-write dest (Rc),
224 printReg(ss, _srcRegIdx[0]);
229 printReg(ss, _srcRegIdx[1]);
232 // just print the first dest... if there's a second one,
233 // it's generally implicit
238 printReg(ss, _destRegIdx[0]);
244 bool passesCondition(uint32_t codes, uint32_t condition)
247 condCodes.bits = codes;
259 return !(condCodes.z | (condCodes.n ^ condCodes.v));
261 return condCodes.z | (condCodes.n ^ condCodes.v);
263 return !(condCodes.n ^ condCodes.v);
265 return (condCodes.n ^ condCodes.v);
266 case GreaterUnsigned:
267 return !(condCodes.c | condCodes.z);
268 case LessOrEqualUnsigned:
269 return (condCodes.c | condCodes.z);
283 panic("Tried testing condition nonexistant "
284 "condition code %d", condition);