Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: src/trusted/validator_ragel/gen_dfa.py

Issue 12090047: Validator_ragel: REX prefix support in gen_dfa.py. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/trusted/validator_ragel/gen_dfa_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2012 The Native Client Authors. All rights reserved. 2 # Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import itertools 6 import itertools
7 import re 7 import re
8 import StringIO 8 import StringIO
9 9
10 10
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 'att-show-name-suffix-q', 107 'att-show-name-suffix-q',
108 'att-show-name-suffix-x', 108 'att-show-name-suffix-x',
109 'att-show-name-suffix-y', 109 'att-show-name-suffix-y',
110 'att-show-name-suffix-w', 110 'att-show-name-suffix-w',
111 111
112 # Spurious REX.W bits (instructions 'in', 'out', 'nop', etc). 112 # Spurious REX.W bits (instructions 'in', 'out', 'nop', etc).
113 'spurious-rex.w' 113 'spurious-rex.w'
114 ] 114 ]
115 115
116 116
117 def Attribute(name):
118 assert name in SUPPORTED_ATTRIBUTES
119 return name
120
121
117 class Operand(object): 122 class Operand(object):
118 123
119 __slots__ = [ 124 __slots__ = [
120 'read_write_attr', 125 'read_write_attr',
121 'arg_type', 126 'arg_type',
122 'size', 127 'size',
123 'implicit', 128 'implicit',
124 'index'] 129 'index']
125 130
126 # Operand read/write modes. 131 # Operand read/write modes.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 185
181 TODO(shcherbina): it is possible that format will also be needed by 186 TODO(shcherbina): it is possible that format will also be needed by
182 validator64 in order to identify zero-extending instruction, but I'm not 187 validator64 in order to identify zero-extending instruction, but I'm not
183 sure how it will be done. 188 sure how it will be done.
184 189
185 Returns: 190 Returns:
186 String like '8bit', '32bit', 'xmm', 'mmx', etc. 191 String like '8bit', '32bit', 'xmm', 'mmx', etc.
187 """ 192 """
188 if self.size == 'b': 193 if self.size == 'b':
189 return '8bit' 194 return '8bit'
195 if self.size == 'w':
196 return '16bit'
197 if self.size == 'd':
198 return '32bit'
199 if self.size == 'q':
200 return '64bit'
190 # TODO(shcherbina): support other formats. 201 # TODO(shcherbina): support other formats.
191 raise NotImplementedError() 202 raise NotImplementedError()
192 203
193 def __str__(self): 204 def __str__(self):
194 return '%s%s%s%s' % ( 205 return '%s%s%s%s' % (
195 self.read_write_attr, 206 self.read_write_attr,
196 self.arg_type, 207 self.arg_type,
197 self.size, 208 self.size,
198 '*' if self.implicit else '') 209 '*' if self.implicit else '')
199 210
200 211
201 class Instruction(object): 212 class Instruction(object):
202 213
203 __slots__ = [ 214 __slots__ = [
204 'name', 215 'name',
205 'operands', 216 'operands',
206 'opcodes', 217 'opcodes',
207 'attributes'] 218 'attributes',
219 'rex']
220
221 class RexStatus(object):
222 __slots__ = [
223 'b_matters',
224 'x_matters',
225 'r_matters',
226 'w_matters',
227 'w_set']
228
229 def __init__(self):
230 self.rex = self.RexStatus()
231 self.rex.b_matters = False
232 self.rex.x_matters = False
233 self.rex.r_matters = False
234 self.rex.w_matters = True
235 self.rex.w_set = False
208 236
209 @staticmethod 237 @staticmethod
210 def Parse(line): 238 def Parse(line):
211 """Parse one line of def file and return initialized Instruction object. 239 """Parse one line of def file and return initialized Instruction object.
212 240
213 Args: 241 Args:
214 line: One line of def file (two or three columns separated by 242 line: One line of def file (two or three columns separated by
215 COLUMN_SEPARATOR). First column defines instruction name and operands, 243 COLUMN_SEPARATOR). First column defines instruction name and operands,
216 second one - opcodes and encoding details, third (optional) 244 second one - opcodes and encoding details, third (optional)
217 one - instruction attributes. 245 one - instruction attributes.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 """Return name in a form suitable to use as part of C identifier. 350 """Return name in a form suitable to use as part of C identifier.
323 351
324 In principle, collisions are possible, but will result in compilation, 352 In principle, collisions are possible, but will result in compilation,
325 failure, so we are not checking for them here for simplicity. 353 failure, so we are not checking for them here for simplicity.
326 354
327 Returns: 355 Returns:
328 Instruction name with all non-alphanumeric characters replaced with '_'. 356 Instruction name with all non-alphanumeric characters replaced with '_'.
329 """ 357 """
330 return re.sub(r'\W', '_', self.name) 358 return re.sub(r'\W', '_', self.name)
331 359
360 def IsVexOrXop(self):
361 return len(self.opcodes) >= 3 and (
362 self.opcodes[0] == '0xc4' or
363 self.opcodes[0] == '0x8f' and self.opcodes[1] != '/0')
khim 2013/01/29 14:07:01 I don't think you need to check self.opcodes[1] he
Vlad Shcherbina 2013/01/29 14:50:37 Changed to what I think is more straightforward ch
364
332 def __str__(self): 365 def __str__(self):
333 return ' '.join([self.name] + map(str, self.operands)) 366 return ' '.join([self.name] + map(str, self.operands))
334 367
335 368
336 DECODER = object() 369 DECODER = object()
337 VALIDATOR = object() 370 VALIDATOR = object()
338 371
339 372
340 class InstructionPrinter(object): 373 class InstructionPrinter(object):
341 374
342 def __init__(self, mode, bitness): 375 def __init__(self, mode, bitness):
343 assert mode in [DECODER, VALIDATOR] 376 assert mode in [DECODER, VALIDATOR]
344 assert bitness in [32, 64] 377 assert bitness in [32, 64]
345 self._mode = mode 378 self._mode = mode
346 self._bitness = bitness 379 self._bitness = bitness
347 self._out = StringIO.StringIO() 380 self._out = StringIO.StringIO()
348 381
349 def GetContent(self): 382 def GetContent(self):
350 return self._out.getvalue() 383 return self._out.getvalue()
351 384
385 def _PrintRexPrefix(self, instruction):
halyavin 2013/01/29 15:15:56 """Print machine for rex prefix."""
386 assert self._bitness == 64
387 assert not instruction.IsVexOrXop()
388
389 if Attribute('norex') in instruction.attributes:
390 return
391
392 if instruction.rex.w_set:
393 self._out.write('REXW_RXB\n')
394 else:
395 self._out.write('REX_RXB?\n')
396
352 def _PrintOpcode(self, instruction): 397 def _PrintOpcode(self, instruction):
halyavin 2013/01/29 15:15:56 """Print machine for opcode."""
353 main_opcode_part = instruction.GetMainOpcodePart() 398 main_opcode_part = instruction.GetMainOpcodePart()
354 if instruction.HasRegisterInOpcode(): 399 if instruction.HasRegisterInOpcode():
355 assert not instruction.HasModRM() 400 assert not instruction.HasModRM()
356 assert not instruction.HasOpcodeInsteadOfImmediate() 401 assert not instruction.HasOpcodeInsteadOfImmediate()
357 402
358 self._out.write(' '.join(main_opcode_part[:-1])) 403 self._out.write(' '.join(main_opcode_part[:-1]))
359 404
360 # Register is encoded in three least significant bits of the last byte 405 # Register is encoded in three least significant bits of the last byte
361 # of the opcode (in 64-bit case REX.B bit also will be involved, but it 406 # of the opcode (in 64-bit case REX.B bit also will be involved, but it
362 # will be handled elsewhere). 407 # will be handled elsewhere).
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 self._out.write('@operand%d_%s\n' % (i, operand.GetFormat())) 441 self._out.write('@operand%d_%s\n' % (i, operand.GetFormat()))
397 442
398 # TODO(shcherbina): print operand sources and extract implicit operands. 443 # TODO(shcherbina): print operand sources and extract implicit operands.
399 444
400 # TODO(shcherbina): print '@last_byte_is_not_immediate' when approptiate. 445 # TODO(shcherbina): print '@last_byte_is_not_immediate' when approptiate.
401 # TODO(shcherbina): print '@modifiable_instruction' in validator64 if 446 # TODO(shcherbina): print '@modifiable_instruction' in validator64 if
402 # attribute 'nacl-amd64-modifiable' is present. 447 # attribute 'nacl-amd64-modifiable' is present.
403 # TODO(shcherbina): print info about CPU features. 448 # TODO(shcherbina): print info about CPU features.
404 # TODO(shcherbina): att_show_name_suffix. 449 # TODO(shcherbina): att_show_name_suffix.
405 450
406 # TODO(shcherbina): print spurious REX stuff (probably not in this 451 if (self._mode == DECODER and
407 # function). 452 self._bitness == 64 and
453 not instruction.IsVexOrXop()):
454 # Note that even if 'norex' attribute is present, we print
455 # @spurious_rex_... actions because NOP needs them (and it has REX
456 # prefix specified as part of the opcode).
457 # TODO(shcherbina): fix that?
458 if not instruction.rex.b_matters:
459 self._out.write('@set_spurious_rex_b\n')
460 if not instruction.rex.x_matters:
461 self._out.write('@set_spurious_rex_x\n')
462 if not instruction.rex.r_matters:
463 self._out.write('@set_spurious_rex_r\n')
464 if not instruction.rex.w_matters:
465 self._out.write('@set_spurious_rex_w\n')
408 466
409 def _PrintOperandSource(self, operand, source): 467 def _PrintOperandSource(self, operand, source):
410 # TODO(shcherbina): add mechanism to check that all operand sources are 468 # TODO(shcherbina): add mechanism to check that all operand sources are
411 # printed. 469 # printed.
412 self._out.write('@operand%d_%s\n' % (operand.index, source)) 470 self._out.write('@operand%d_%s\n' % (operand.index, source))
413 471
414 def _PrintImplicitOperandSources(self, instruction): 472 def _PrintImplicitOperandSources(self, instruction):
415 """Print actions specifying sources of implicit operands. 473 """Print actions specifying sources of implicit operands.
416 474
417 Args: 475 Args:
418 instruction: instruction. 476 instruction: instruction.
419 477
420 Returns: 478 Returns:
421 None. 479 None.
422 """ 480 """
423 operand = instruction.FindOperand('a') 481 operand = instruction.FindOperand('a')
424 if operand is not None: 482 if operand is not None:
425 self._PrintOperandSource(operand, 'rax') 483 self._PrintOperandSource(operand, 'rax')
426 # TODO(shcherbina): handle other implicit operands. 484 # TODO(shcherbina): handle other implicit operands.
427 485
428 def PrintInstructionWithoutModRM(self, instruction): 486 def PrintInstructionWithoutModRM(self, instruction):
429 # TODO(shcherbina): print legacy prefixes. 487 # TODO(shcherbina): print legacy prefixes.
430 # TODO(shcherbina): print REX prefix.
431 488
489 assert not instruction.IsVexOrXop()
khim 2013/01/29 14:07:01 Why not? Where and how do you plan to print vzeroa
Vlad Shcherbina 2013/01/29 14:50:37 Right, marked as 'not implemented'.
432 assert not instruction.HasModRM() 490 assert not instruction.HasModRM()
491
492 if self._bitness == 64:
493 self._PrintRexPrefix(instruction)
494
433 assert not instruction.HasOpcodeInsteadOfImmediate(), 'not supported yet' 495 assert not instruction.HasOpcodeInsteadOfImmediate(), 'not supported yet'
434 496
435 self._PrintOpcode(instruction) 497 self._PrintOpcode(instruction)
436 self._out.write('\n') 498 self._out.write('\n')
437 499
438 self._PrintSignature(instruction) 500 self._PrintSignature(instruction)
439 self._PrintImplicitOperandSources(instruction) 501 self._PrintImplicitOperandSources(instruction)
440 502
441 # TODO(shcherbina): print immediate args. 503 # TODO(shcherbina): print immediate args.
442 504
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 592
531 return result 593 return result
532 594
533 595
534 def main(): 596 def main():
535 pass 597 pass
536 598
537 599
538 if __name__ == '__main__': 600 if __name__ == '__main__':
539 main() 601 main()
OLDNEW
« no previous file with comments | « no previous file | src/trusted/validator_ragel/gen_dfa_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698