microasm.isa (4336:bd6ab22f8e11) microasm.isa (4338:24d31b35bcf9)
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:

--- 121 unchanged lines hidden (view full) ---

130 def specializeInst(name, Name, code, opTypes):
131 opNum = len(opTypes) - 1
132 while len(opTypes):
133 # print "Building a composite op with tags", opTypes
134 # print "And code", code
135 opNum = len(opTypes) - 1
136 # A regular expression to find the operand placeholders we're
137 # interested in.
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:

--- 121 unchanged lines hidden (view full) ---

130 def specializeInst(name, Name, code, opTypes):
131 opNum = len(opTypes) - 1
132 while len(opTypes):
133 # print "Building a composite op with tags", opTypes
134 # print "And code", code
135 opNum = len(opTypes) - 1
136 # A regular expression to find the operand placeholders we're
137 # interested in.
138 opRe = re.compile("%%(?P<operandNum>%d)(?=[^0-9]|$)" % opNum)
138 opRe = re.compile("\\^(?P<operandNum>%d)(?=[^0-9]|$)" % opNum)
139
140 # Parse the operand type strign we're working with
139
140 # Parse the operand type strign we're working with
141 print "About to parse tag %s" % opTypes[opNum]
142 opType = OpType(opTypes[opNum])
143
144 if opType.reg:
145 #Figure out what to do with fixed register operands
146 if opType.reg in ("Ax", "Bx", "Cx", "Dx"):
141 opType = OpType(opTypes[opNum])
142
143 if opType.reg:
144 #Figure out what to do with fixed register operands
145 if opType.reg in ("Ax", "Bx", "Cx", "Dx"):
147 code = opRe.sub("{INTREG_R%s}" % opType.reg.upper(), code)
146 code = opRe.sub("%%{INTREG_R%s}" % opType.reg.upper(), code)
148 elif opType.reg == "Al":
149 # We need a way to specify register width
147 elif opType.reg == "Al":
148 # We need a way to specify register width
150 code = opRe.sub("{INTREG_RAX}", code)
149 code = opRe.sub("%{INTREG_RAX}", code)
151 else:
152 print "Didn't know how to encode fixed register %s!" % opType.reg
153 elif opType.tag == None or opType.size == None:
154 raise Exception, "Problem parsing operand tag: %s" % opType.tag
155 elif opType.tag in ("C", "D", "G", "P", "S", "T", "V"):
156 # Use the "reg" field of the ModRM byte to select the register
150 else:
151 print "Didn't know how to encode fixed register %s!" % opType.reg
152 elif opType.tag == None or opType.size == None:
153 raise Exception, "Problem parsing operand tag: %s" % opType.tag
154 elif opType.tag in ("C", "D", "G", "P", "S", "T", "V"):
155 # Use the "reg" field of the ModRM byte to select the register
157 code = opRe.sub("{(uint8_t)MODRM_REG}", code)
156 code = opRe.sub("%{(uint8_t)MODRM_REG}", code)
158 elif opType.tag in ("E", "Q", "W"):
159 # This might refer to memory or to a register. We need to
160 # divide it up farther.
157 elif opType.tag in ("E", "Q", "W"):
158 # This might refer to memory or to a register. We need to
159 # divide it up farther.
161 regCode = opRe.sub("{(uint8_t)MODRM_RM}", code)
160 regCode = opRe.sub("%{(uint8_t)MODRM_RM}", code)
162 regTypes = copy.copy(opTypes)
163 regTypes.pop(-1)
164 # This needs to refer to memory, but we'll fill in the details
165 # later. It needs to take into account unaligned memory
166 # addresses.
161 regTypes = copy.copy(opTypes)
162 regTypes.pop(-1)
163 # This needs to refer to memory, but we'll fill in the details
164 # later. It needs to take into account unaligned memory
165 # addresses.
167 memCode = opRe.sub("0", code)
166 memCode = opRe.sub("%0", code)
168 memTypes = copy.copy(opTypes)
169 memTypes.pop(-1)
170 return doSplitDecode(name, Name, specializeInst, "MODRM_MOD",
171 {"3" : (regCode, regTypes)}, (memCode, memTypes))
172 elif opType.tag in ("I", "J"):
173 # Immediates are already in the instruction, so don't leave in
174 # those parameters
167 memTypes = copy.copy(opTypes)
168 memTypes.pop(-1)
169 return doSplitDecode(name, Name, specializeInst, "MODRM_MOD",
170 {"3" : (regCode, regTypes)}, (memCode, memTypes))
171 elif opType.tag in ("I", "J"):
172 # Immediates are already in the instruction, so don't leave in
173 # those parameters
175 code = opRe.sub("", code)
174 code = opRe.sub("${IMMEDIATE}", code)
176 elif opType.tag == "M":
177 # This needs to refer to memory, but we'll fill in the details
178 # later. It needs to take into account unaligned memory
179 # addresses.
175 elif opType.tag == "M":
176 # This needs to refer to memory, but we'll fill in the details
177 # later. It needs to take into account unaligned memory
178 # addresses.
180 code = opRe.sub("0", code)
179 code = opRe.sub("%0", code)
181 elif opType.tag in ("PR", "R", "VR"):
182 # There should probably be a check here to verify that mod
183 # is equal to 11b
180 elif opType.tag in ("PR", "R", "VR"):
181 # There should probably be a check here to verify that mod
182 # is equal to 11b
184 code = opRe.sub("{(uint8_t)MODRM_RM}", code)
183 code = opRe.sub("%{(uint8_t)MODRM_RM}", code)
185 else:
186 raise Exception, "Unrecognized tag %s." % opType.tag
187 opTypes.pop(-1)
188
189 # At this point, we've built up "code" to have all the necessary extra
190 # instructions needed to implement whatever types of operands were
191 # specified. Now we'll assemble it it into a microOp sequence.
192 ops = assembleMicro(code)

--- 25 unchanged lines hidden (view full) ---

218 if val:
219 text += ", true"
220 else:
221 text += ", false"
222 return text
223
224 def getAllocator(self, *microFlags):
225 args = ''
184 else:
185 raise Exception, "Unrecognized tag %s." % opType.tag
186 opTypes.pop(-1)
187
188 # At this point, we've built up "code" to have all the necessary extra
189 # instructions needed to implement whatever types of operands were
190 # specified. Now we'll assemble it it into a microOp sequence.
191 ops = assembleMicro(code)

--- 25 unchanged lines hidden (view full) ---

217 if val:
218 text += ", true"
219 else:
220 text += ", false"
221 return text
222
223 def getAllocator(self, *microFlags):
224 args = ''
225 signature = "<"
226 emptySig = True
226 for arg in self.args:
227 for arg in self.args:
227 if arg.has_key("operandConst"):
228 args += ", %s" % arg["operandConst"]
229 elif arg.has_key("operandCode"):
230 args += ", %s" % arg["operandCode"]
228 if not emptySig:
229 signature += ", "
230 emptySig = False
231 if arg.has_key("operandImm"):
232 args += ", %s" % arg["operandImm"]
233 signature += ImmOpType
234 elif arg.has_key("operandReg"):
235 args += ", %s" % arg["operandReg"]
236 signature += RegOpType
231 elif arg.has_key("operandLabel"):
232 raise Exception, "Found a label while creating allocator string."
233 else:
234 raise Exception, "Unrecognized operand type."
237 elif arg.has_key("operandLabel"):
238 raise Exception, "Found a label while creating allocator string."
239 else:
240 raise Exception, "Unrecognized operand type."
235 return 'new %s(machInst%s%s)' % (self.className, self.microFlagsText(microFlags), args)
241 signature += ">"
242 return 'new %s%s(machInst%s%s)' % (self.className, signature, self.microFlagsText(microFlags), args)
236}};
237
238let {{
239 def buildLabelDict(ops):
240 labels = {}
241 micropc = 0
242 for op in ops:
243 if op.label:

--- 11 unchanged lines hidden (view full) ---

255 orig_code = code
256 # A list of the statements we've found thus far
257 statements = []
258
259 # Regular expressions to pull each piece of the statement out at a
260 # time. Each expression expects the thing it's looking for to be at
261 # the beginning of the line, so the previous component is stripped
262 # before continuing.
243}};
244
245let {{
246 def buildLabelDict(ops):
247 labels = {}
248 micropc = 0
249 for op in ops:
250 if op.label:

--- 11 unchanged lines hidden (view full) ---

262 orig_code = code
263 # A list of the statements we've found thus far
264 statements = []
265
266 # Regular expressions to pull each piece of the statement out at a
267 # time. Each expression expects the thing it's looking for to be at
268 # the beginning of the line, so the previous component is stripped
269 # before continuing.
263 labelRe = re.compile(r'^[ \t]*(?P<label>[a-zA-Z_]\w*)[ \t]:')
270 labelRe = re.compile(r'^[ \t]*(?P<label>\w\w*)[ \t]:')
264 lineRe = re.compile(r'^(?P<line>[^\n][^\n]*)$')
265 classRe = re.compile(r'^[ \t]*(?P<className>[a-zA-Z_]\w*)')
266 # This recognizes three different flavors of operands:
267 # 1. Raw decimal numbers composed of digits between 0 and 9
268 # 2. Code beginning with "{" and continuing until the first "}"
269 # ^ This one might need revising
270 # 3. A label, which starts with a capital or small letter, or
271 # underscore, which is optionally followed by a sequence of
272 # capital or small letters, underscores, or digts between 0 and 9
273 opRe = re.compile( \
271 lineRe = re.compile(r'^(?P<line>[^\n][^\n]*)$')
272 classRe = re.compile(r'^[ \t]*(?P<className>[a-zA-Z_]\w*)')
273 # This recognizes three different flavors of operands:
274 # 1. Raw decimal numbers composed of digits between 0 and 9
275 # 2. Code beginning with "{" and continuing until the first "}"
276 # ^ This one might need revising
277 # 3. A label, which starts with a capital or small letter, or
278 # underscore, which is optionally followed by a sequence of
279 # capital or small letters, underscores, or digts between 0 and 9
280 opRe = re.compile( \
274 r'^[ \t]*((?P<operandLabel>[a-zA-Z_]\w*)|(?P<operandConst>[0-9][0-9]*)|(\{(?P<operandCode>[^}]*)\}))')
281 r'^[ \t]*((\@(?P<operandLabel0>\w\w*))|' +
282 r'(\@\{(?P<operandLabel1>[^}]*)\})|' +
283 r'(\%(?P<operandReg0>\w\w*))|' +
284 r'(\%\{(?P<operandReg1>[^}]*)\})|' +
285 r'(\$(?P<operandImm0>\w\w*))|' +
286 r'(\$\{(?P<operandImm1>[^}]*)\}))')
275 lineMatch = lineRe.search(code)
276 while lineMatch != None:
277 statement = MicroOpStatement()
278 # Get a line and seperate it from the rest of the code
279 line = lineMatch.group("line")
280 orig_line = line
281 # print "Parsing line %s" % line
282 code = lineRe.sub('', code, 1)

--- 22 unchanged lines hidden (view full) ---

305 statement.args = []
306 opMatch = opRe.search(line)
307 while opMatch is not None:
308 statement.args.append({})
309 # args is a list of dicts which collect different
310 # representations of operand values. Different forms might be
311 # needed in different places, for instance to replace a label
312 # with an offset.
287 lineMatch = lineRe.search(code)
288 while lineMatch != None:
289 statement = MicroOpStatement()
290 # Get a line and seperate it from the rest of the code
291 line = lineMatch.group("line")
292 orig_line = line
293 # print "Parsing line %s" % line
294 code = lineRe.sub('', code, 1)

--- 22 unchanged lines hidden (view full) ---

317 statement.args = []
318 opMatch = opRe.search(line)
319 while opMatch is not None:
320 statement.args.append({})
321 # args is a list of dicts which collect different
322 # representations of operand values. Different forms might be
323 # needed in different places, for instance to replace a label
324 # with an offset.
313 for opType in ("operandLabel", "operandConst", "operandCode"):
325 for opType in ("operandLabel0", "operandReg0", "operandImm0",
326 "operandLabel1", "operandReg1", "operandImm1"):
314 if opMatch.group(opType):
327 if opMatch.group(opType):
315 statement.args[-1][opType] = opMatch.group(opType)
328 statement.args[-1][opType[:-1]] = opMatch.group(opType)
316 if len(statement.args[-1]) == 0:
317 print "Problem parsing operand in statement: %s" \
318 % orig_line
319 line = opRe.sub('', line, 1)
320 # print "Found operand %s." % statement.args[-1]
321 opMatch = opRe.search(line)
322 # print "Found operands", statement.args
323

--- 9 unchanged lines hidden (view full) ---

333 for statement in statements:
334 for arg in statement.args:
335 if arg.has_key("operandLabel"):
336 if not labels.has_key(arg["operandLabel"]):
337 raise Exception, "Unrecognized label: %s." % arg["operandLabel"]
338 # This is assuming that intra microcode branches go to
339 # the next micropc + displacement, or
340 # micropc + 1 + displacement.
329 if len(statement.args[-1]) == 0:
330 print "Problem parsing operand in statement: %s" \
331 % orig_line
332 line = opRe.sub('', line, 1)
333 # print "Found operand %s." % statement.args[-1]
334 opMatch = opRe.search(line)
335 # print "Found operands", statement.args
336

--- 9 unchanged lines hidden (view full) ---

346 for statement in statements:
347 for arg in statement.args:
348 if arg.has_key("operandLabel"):
349 if not labels.has_key(arg["operandLabel"]):
350 raise Exception, "Unrecognized label: %s." % arg["operandLabel"]
351 # This is assuming that intra microcode branches go to
352 # the next micropc + displacement, or
353 # micropc + 1 + displacement.
341 arg["operandConst"] = labels[arg["operandLabel"]] - micropc - 1
354 arg["operandImm"] = labels[arg["operandLabel"]] - micropc - 1
342 micropc += 1
343 return statements
344}};
355 micropc += 1
356 return statements
357}};