1// -*- mode:c++ -*- 2 3// Copyright (c) 2007 The Hewlett-Packard Development Company 4// All rights reserved. 5// 6// Redistribution and use of this software in source and binary forms, 7// with or without modification, are permitted provided that the 8// following conditions are met: 9// 10// The software must be used only for Non-Commercial Use which means any 11// use which is NOT directed to receiving any direct monetary 12// compensation for, or commercial advantage from such use. Illustrative 13// examples of non-commercial use are academic research, personal study, 14// teaching, education and corporate research & development. 15// Illustrative examples of commercial use are distributing products for 16// commercial advantage and providing services using the software for 17// commercial advantage. 18// 19// If you wish to use this software or functionality therein that may be 20// covered by patents for commercial use, please contact: 21// Director of Intellectual Property Licensing 22// Office of Strategy and Technology 23// Hewlett-Packard Company 24// 1501 Page Mill Road 25// Palo Alto, California 94304 26// 27// Redistributions of source code must retain the above copyright notice, 28// this list of conditions and the following disclaimer. Redistributions 29// in binary form must reproduce the above copyright notice, this list of 30// conditions and the following disclaimer in the documentation and/or 31// other materials provided with the distribution. Neither the name of 32// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 33// contributors may be used to endorse or promote products derived from 34// this software without specific prior written permission. No right of 35// sublicense is granted herewith. Derivatives of the software and 36// output created using the software may be prepared, but only for 37// Non-Commercial Uses. Derivatives of the software may be shared with 38// others provided: (i) the others agree to abide by the list of 39// conditions herein which includes the Non-Commercial Use restrictions; 40// and (ii) such Derivatives of the software include the above copyright 41// notice to acknowledge the contribution from this software where 42// applicable, this list of conditions and the disclaimer below. 43// 44// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 45// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 46// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 47// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 48// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 49// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 50// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 51// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 52// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 53// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 54// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55// 56// Authors: Gabe Black 57 58////////////////////////////////////////////////////////////////////////////// 59// 60// Architecture independent 61// 62 63// Execute method for macroops. 64def template MacroExecPanic {{ 65 Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const 66 { 67 panic("Tried to execute macroop directly!"); 68 return NoFault; 69 } 70}}; 71 72output header {{ 73 74 // Base class for combinationally generated macroops
| 1// -*- mode:c++ -*- 2 3// Copyright (c) 2007 The Hewlett-Packard Development Company 4// All rights reserved. 5// 6// Redistribution and use of this software in source and binary forms, 7// with or without modification, are permitted provided that the 8// following conditions are met: 9// 10// The software must be used only for Non-Commercial Use which means any 11// use which is NOT directed to receiving any direct monetary 12// compensation for, or commercial advantage from such use. Illustrative 13// examples of non-commercial use are academic research, personal study, 14// teaching, education and corporate research & development. 15// Illustrative examples of commercial use are distributing products for 16// commercial advantage and providing services using the software for 17// commercial advantage. 18// 19// If you wish to use this software or functionality therein that may be 20// covered by patents for commercial use, please contact: 21// Director of Intellectual Property Licensing 22// Office of Strategy and Technology 23// Hewlett-Packard Company 24// 1501 Page Mill Road 25// Palo Alto, California 94304 26// 27// Redistributions of source code must retain the above copyright notice, 28// this list of conditions and the following disclaimer. Redistributions 29// in binary form must reproduce the above copyright notice, this list of 30// conditions and the following disclaimer in the documentation and/or 31// other materials provided with the distribution. Neither the name of 32// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 33// contributors may be used to endorse or promote products derived from 34// this software without specific prior written permission. No right of 35// sublicense is granted herewith. Derivatives of the software and 36// output created using the software may be prepared, but only for 37// Non-Commercial Uses. Derivatives of the software may be shared with 38// others provided: (i) the others agree to abide by the list of 39// conditions herein which includes the Non-Commercial Use restrictions; 40// and (ii) such Derivatives of the software include the above copyright 41// notice to acknowledge the contribution from this software where 42// applicable, this list of conditions and the disclaimer below. 43// 44// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 45// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 46// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 47// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 48// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 49// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 50// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 51// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 52// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 53// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 54// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55// 56// Authors: Gabe Black 57 58////////////////////////////////////////////////////////////////////////////// 59// 60// Architecture independent 61// 62 63// Execute method for macroops. 64def template MacroExecPanic {{ 65 Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const 66 { 67 panic("Tried to execute macroop directly!"); 68 return NoFault; 69 } 70}}; 71 72output header {{ 73 74 // Base class for combinationally generated macroops
|
75 class MacroOp : public StaticInst
| 75 class Macroop : public StaticInst
|
76 { 77 protected:
| 76 { 77 protected:
|
78 const uint32_t numMicroOps;
| 78 const uint32_t numMicroops;
|
79 80 //Constructor.
| 79 80 //Constructor.
|
81 MacroOp(const char *mnem, ExtMachInst _machInst, 82 uint32_t _numMicroOps)
| 81 Macroop(const char *mnem, ExtMachInst _machInst, 82 uint32_t _numMicroops)
|
83 : StaticInst(mnem, _machInst, No_OpClass),
| 83 : StaticInst(mnem, _machInst, No_OpClass),
|
84 numMicroOps(_numMicroOps)
| 84 numMicroops(_numMicroops)
|
85 {
| 85 {
|
86 assert(numMicroOps); 87 microOps = new StaticInstPtr[numMicroOps]; 88 flags[IsMacroOp] = true;
| 86 assert(numMicroops); 87 microops = new StaticInstPtr[numMicroops]; 88 flags[IsMacroop] = true;
|
89 } 90
| 89 } 90
|
91 ~MacroOp()
| 91 ~Macroop()
|
92 {
| 92 {
|
93 delete [] microOps;
| 93 delete [] microops;
|
94 } 95
| 94 } 95
|
96 StaticInstPtr * microOps;
| 96 StaticInstPtr * microops;
|
97
| 97
|
98 StaticInstPtr fetchMicroOp(MicroPC microPC)
| 98 StaticInstPtr fetchMicroop(MicroPC microPC)
|
99 {
| 99 {
|
100 assert(microPC < numMicroOps); 101 return microOps[microPC];
| 100 assert(microPC < numMicroops); 101 return microops[microPC];
|
102 } 103 104 std::string generateDisassembly(Addr pc, 105 const SymbolTable *symtab) const 106 { 107 return mnemonic; 108 } 109 110 %(MacroExecPanic)s 111 }; 112}}; 113 114// Basic instruction class declaration template. 115def template MacroDeclare {{
| 102 } 103 104 std::string generateDisassembly(Addr pc, 105 const SymbolTable *symtab) const 106 { 107 return mnemonic; 108 } 109 110 %(MacroExecPanic)s 111 }; 112}}; 113 114// Basic instruction class declaration template. 115def template MacroDeclare {{
|
116 namespace X86Microop
| 116 namespace X86Macroop
|
117 { 118 /** 119 * Static instruction class for "%(mnemonic)s". 120 */ 121 class %(class_name)s : public %(base_class)s 122 { 123 public: 124 // Constructor.
| 117 { 118 /** 119 * Static instruction class for "%(mnemonic)s". 120 */ 121 class %(class_name)s : public %(base_class)s 122 { 123 public: 124 // Constructor.
|
125 %(class_name)s(ExtMachInst machInst);
| 125 %(class_name)s(ExtMachInst machInst, EmulEnv env);
|
126 }; 127 }; 128}}; 129 130// Basic instruction class constructor template. 131def template MacroConstructor {{
| 126 }; 127 }; 128}}; 129 130// Basic instruction class constructor template. 131def template MacroConstructor {{
|
132 inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 133 : %(base_class)s("%(mnemonic)s", machInst, %(num_micro_ops)s)
| 132 inline X86Macroop::%(class_name)s::%(class_name)s(ExtMachInst machInst, EmulEnv env) 133 : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s)
|
134 { 135 %(constructor)s;
| 134 { 135 %(constructor)s;
|
136 //alloc_micro_ops is the code that sets up the microOps
| 136 //alloc_microops is the code that sets up the microops
|
137 //array in the parent class.
| 137 //array in the parent class.
|
138 %(alloc_micro_ops)s;
| 138 %(alloc_microops)s;
|
139 } 140}}; 141 142////////////////////////////////////////////////////////////////////////////// 143// 144// X86 specific 145// 146 147let {{ 148 from micro_asm import Combinational_Macroop, Rom_Macroop 149 class X86Macroop(Combinational_Macroop): 150 def __init__(self, name): 151 super(X86Macroop, self).__init__(name) 152 self.directives = { 153 } 154 self.declared = False 155 def getAllocator(self, env):
| 139 } 140}}; 141 142////////////////////////////////////////////////////////////////////////////// 143// 144// X86 specific 145// 146 147let {{ 148 from micro_asm import Combinational_Macroop, Rom_Macroop 149 class X86Macroop(Combinational_Macroop): 150 def __init__(self, name): 151 super(X86Macroop, self).__init__(name) 152 self.directives = { 153 } 154 self.declared = False 155 def getAllocator(self, env):
|
156 return "new X86Macroop::%s(machInst)" % self.name
| 156 return "new X86Macroop::%s(machInst, %s)" % (self.name, env.getAllocator())
|
157 def getDeclaration(self): 158 #FIXME This first parameter should be the mnemonic. I need to 159 #write some code which pulls that out 160 iop = InstObjParams(self.name, self.name, "Macroop", {"code" : ""}) 161 return MacroDeclare.subst(iop); 162 def getDefinition(self): 163 #FIXME This first parameter should be the mnemonic. I need to 164 #write some code which pulls that out 165 numMicroops = len(self.microops) 166 allocMicroops = '' 167 micropc = 0 168 for op in self.microops: 169 allocMicroops += \
| 157 def getDeclaration(self): 158 #FIXME This first parameter should be the mnemonic. I need to 159 #write some code which pulls that out 160 iop = InstObjParams(self.name, self.name, "Macroop", {"code" : ""}) 161 return MacroDeclare.subst(iop); 162 def getDefinition(self): 163 #FIXME This first parameter should be the mnemonic. I need to 164 #write some code which pulls that out 165 numMicroops = len(self.microops) 166 allocMicroops = '' 167 micropc = 0 168 for op in self.microops: 169 allocMicroops += \
|
170 "microOps[%d] = %s;\n" % \
| 170 "microops[%d] = %s;\n" % \
|
171 (micropc, op.getAllocator(True, False, 172 micropc == 0, 173 micropc == numMicroops - 1)) 174 micropc += 1 175 iop = InstObjParams(self.name, self.name, "Macroop",
| 171 (micropc, op.getAllocator(True, False, 172 micropc == 0, 173 micropc == numMicroops - 1)) 174 micropc += 1 175 iop = InstObjParams(self.name, self.name, "Macroop",
|
176 {"code" : "", "num_micro_ops" : numMicroops, 177 "alloc_micro_ops" : allocMicroops})
| 176 {"code" : "", "num_microops" : numMicroops, 177 "alloc_microops" : allocMicroops})
|
178 return MacroConstructor.subst(iop); 179}}; 180 181output header {{ 182 struct EmulEnv 183 { 184 X86ISA::RegIndex reg; 185 X86ISA::RegIndex regm; 186 uint64_t immediate; 187 uint64_t displacement; 188 int addressSize; 189 int dataSize; 190 191 EmulEnv(X86ISA::RegIndex _reg, X86ISA::RegIndex _regm, 192 uint64_t _immediate, uint64_t _displacement, 193 int _addressSize, int _dataSize) : 194 reg(_reg), regm(_regm), 195 immediate(_immediate), displacement(_displacement), 196 addressSize(_addressSize), dataSize(_dataSize) 197 {;} 198 }; 199}}; 200 201let {{ 202 class EmulEnv(object): 203 def __init__(self):
| 178 return MacroConstructor.subst(iop); 179}}; 180 181output header {{ 182 struct EmulEnv 183 { 184 X86ISA::RegIndex reg; 185 X86ISA::RegIndex regm; 186 uint64_t immediate; 187 uint64_t displacement; 188 int addressSize; 189 int dataSize; 190 191 EmulEnv(X86ISA::RegIndex _reg, X86ISA::RegIndex _regm, 192 uint64_t _immediate, uint64_t _displacement, 193 int _addressSize, int _dataSize) : 194 reg(_reg), regm(_regm), 195 immediate(_immediate), displacement(_displacement), 196 addressSize(_addressSize), dataSize(_dataSize) 197 {;} 198 }; 199}}; 200 201let {{ 202 class EmulEnv(object): 203 def __init__(self):
|
204 self.reg = "Not specified" 205 self.regm = "Not specified"
| 204 self.reg = "0" 205 self.regUsed = False 206 self.regm = "0" 207 self.regmUsed = False
|
206 self.immediate = "IMMEDIATE" 207 self.displacement = "DISPLACEMENT" 208 self.addressSize = "ADDRSIZE" 209 self.dataSize = "OPSIZE" 210 def getAllocator(self):
| 208 self.immediate = "IMMEDIATE" 209 self.displacement = "DISPLACEMENT" 210 self.addressSize = "ADDRSIZE" 211 self.dataSize = "OPSIZE" 212 def getAllocator(self):
|
211 return "EmulEmv(%(reg)s, %(regm)s, %(immediate)s, %(displacement)s, %(addressSize)s, %(dataSize)s)" % \ 212 self.__dict__()
| 213 return '''EmulEnv(%(reg)s, 214 %(regm)s, 215 %(immediate)s, 216 %(displacement)s, 217 %(addressSize)s, 218 %(dataSize)s)''' % \ 219 self.__dict__ 220 def addReg(self, reg): 221 print "Adding reg \"%s\"" % reg 222 if not self.regUsed: 223 print "Added as reg" 224 self.reg = reg 225 self.regUsed = True 226 elif not self.regmUsed: 227 print "Added as regm" 228 self.regm = reg 229 self.regmUsed = True 230 else: 231 raise Exception, "EmulEnv is out of register specialization spots."
|
213}}; 214 215let {{ 216 def genMacroop(Name, env):
| 232}}; 233 234let {{ 235 def genMacroop(Name, env):
|
| 236 blocks = OutputBlocks()
|
217 if not macroopDict.has_key(Name): 218 raise Exception, "Unrecognized instruction: %s" % Name 219 macroop = macroopDict[Name] 220 if not macroop.declared:
| 237 if not macroopDict.has_key(Name): 238 raise Exception, "Unrecognized instruction: %s" % Name 239 macroop = macroopDict[Name] 240 if not macroop.declared:
|
221 global header_output 222 global decoder_output 223 header_output = macroop.getDeclaration() 224 decoder_output = macroop.getDefinition() 225 return "return %s;\n" % macroop.getAllocator(env)
| 241 blocks.header_output = macroop.getDeclaration() 242 blocks.decoder_output = macroop.getDefinition() 243 macroop.declared = True 244 blocks.decode_block = "return %s;\n" % macroop.getAllocator(env) 245 return blocks
|
226}};
| 246}};
|