1 # Copyright 2016, VIXL authors 2 # All rights reserved. 3 # 4 # Redistribution and use in source and binary forms, with or without 5 # modification, are permitted provided that the following conditions are met: 6 # 7 # * Redistributions of source code must retain the above copyright notice, 8 # this list of conditions and the following disclaimer. 9 # * Redistributions in binary form must reproduce the above copyright notice, 10 # this list of conditions and the following disclaimer in the documentation 11 # and/or other materials provided with the distribution. 12 # * Neither the name of ARM Limited nor the names of its contributors may be 13 # used to endorse or promote products derived from this software without 14 # specific prior written permission. 15 # 16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 # OR TORT (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. 26 27 class OperandBase(object): 28 """ 29 Base class for operands. An operand represents an argument passed to the 30 macro-assembler to generate an instruction. For example, registers, conditions 31 or C++ `Operand` and `MemOperand` objects are operands. We can think of them 32 as "assemble-time" data. 33 34 An operand is described with a type name, corresponding to the C++ type used 35 to represent it (e.g. "Register", "ShiftType", "MemOperand", ...) and a name 36 to identify it. 37 38 Attributes: 39 name Name for the operand. It is used to declare variable names. 40 type_name C++ type for the operand. 41 """ 42 43 def __init__(self, name, type_name): 44 self.name = name 45 self.type_name = type_name 46 47 @staticmethod 48 def __iter__(): 49 """ 50 Operand types have to act as an iterator so that `generator.OperandList` can 51 unwrap them (see `OperandWrapper` and `generator.OperandList.unwrap()`). 52 """ 53 raise NotImplementedError() 54 55 @staticmethod 56 def GetArgumentType(): 57 """ 58 Return the type to be printed when passing this operand as an argument. For 59 example, we could pass it by value or by reference. 60 """ 61 raise NotImplementedError() 62 63 @staticmethod 64 def Declare(): 65 """ 66 Generate code to declare the operand `struct Operands`. 67 """ 68 raise NotImplementedError() 69 70 @staticmethod 71 def Instantiate(): 72 """ 73 Generate code to instantiate the operand from inside a `kTests` loop, with 74 `i` being the index variable. 75 """ 76 raise NotImplementedError() 77 78 79 class Operand(OperandBase): 80 """ 81 Representation of a single operand. An operand has different variants 82 (e.g. "r0", "r1", "LSL", ...) and a default one. 83 84 Attributes: 85 variants List of variants the operand can take. 86 default Default variant to use. 87 88 Note that the `variants` and `default` attributes are not used from inside the 89 class. They are public fields used by the `TestCase` object to generate C++. 90 """ 91 92 def __init__(self, name, type_name, variants, default): 93 super().__init__(name, type_name) 94 self.variants = variants 95 self.default = default 96 97 def __iter__(self): 98 """ 99 Iterating over a single operand just yields the operand object. 100 """ 101 yield self 102 103 def GetArgumentType(self): 104 """ 105 A single operand is passed to the macro-assembler by value. We just print 106 the type name as it is. 107 """ 108 return self.type_name 109 110 def Declare(self): 111 """ 112 Generate code to declare the operand as a single member in 113 `struct Operands`. 114 """ 115 return "{type_name} {name};".format(type_name=self.type_name, 116 name=self.name) 117 118 def Instantiate(self): 119 """ 120 Generate code to instantiate the operand as a single local variable. 121 """ 122 code = "{type_name} {name} = kTests[i].operands.{name};" 123 return code.format(type_name=self.type_name, name=self.name) 124 125 126 class OperandWrapper(OperandBase): 127 """ 128 Representation for an operand type which wraps a list of more operands. It 129 corresponds to C++ objects such as `Operand` or `MemOperand`. 130 131 Attributes: 132 operand_list List of operand that this object wraps. 133 """ 134 135 def __init__(self, name, type_name, operand_list): 136 super().__init__(name, type_name) 137 self.operand_list = operand_list 138 139 def __iter__(self): 140 """ 141 Iterate through the list of operands. This is required by 142 `OperandList.unwrap()`. 143 """ 144 return iter(self.operand_list) 145 146 def GetArgumentType(self): 147 """ 148 An operand wrapper object will be passed to the macro-assembler by 149 reference. 150 """ 151 return "const " + self.type_name + "&" 152 153 def Declare(self): 154 """ 155 An `OperandWrapper` object does not need to be declared in 156 `struct Operands`. Although we do need to declare all underlying operands. 157 """ 158 return "\n".join([operand.Declare() for operand in self.operand_list]) 159 160 def Instantiate(self): 161 """ 162 Instantiate the underlying operands first and then finally instantiate the 163 wrapper object. 164 165 For example, if the object represents a C++ `Operand` type for a shifted 166 register we would get: 167 168 ~~~ 169 Register rm = kTests[i].operands.rm; 170 Shift shift_type = kTests[i].operands.shift_type; 171 uint32_t amount = kTests[i].operands.amount; 172 Operand op(rm, shift_type, amount); 173 ~~~ 174 """ 175 instantiate_wrapped_operands = "\n".join([ 176 operand.Instantiate() 177 for operand in self.operand_list 178 ]) 179 instantiate_this = "{type_name} {name}({arguments});".format( 180 type_name=self.type_name, 181 name=self.name, 182 arguments=", ".join([operand.name for operand in self.operand_list])) 183 return instantiate_wrapped_operands + "\n" + instantiate_this 184 185 186 class Input(object): 187 """ 188 Base class for all input types instantiated from a JSON description. This 189 class should not be instantiated directly, instead, we create subclasses for 190 each kind of input we have. 191 192 As opposed to operands, an input represents data passed to an instruction at 193 runtime. For example, it will be the value you write to a register before 194 executing the instruction under test. 195 196 Attributes: 197 name Name of the input. It is used to declare variable names. 198 199 values List of values this input can take. 200 default Default value to use. 201 """ 202 203 def __init__(self, name, values, default): 204 self.name = name 205 206 self.values = values 207 self.default = default 208 209 @staticmethod 210 def Prologue(): 211 """ 212 Return a string describing what C++ code to emit before the instruction 213 under test is emitted. 214 """ 215 raise NotImplementedError() 216 217 @staticmethod 218 def Epilogue(): 219 """ 220 Return a string describing what C++ code to emit after the instruction under 221 test is emitted. 222 """ 223 raise NotImplementedError() 224 225 @staticmethod 226 def Declare(): 227 """ 228 Generate code to declare the input in `struct Inputs`. 229 """ 230 raise NotImplementedError() 231 232 @staticmethod 233 def PrintInput(suffix = ""): 234 """ 235 Generate code to print the input referred to by `self.name`. Optionally add 236 `suffix` to the input's name. 237 """ 238 raise NotImplementedError() 239 240 @staticmethod 241 def PrintOutput(): 242 """ 243 Generate code to print the input from the result buffer, indexed with `i` 244 and `j`. 245 """ 246 raise NotImplementedError() 247 248 @staticmethod 249 def InstantiateResult(suffix = ""): 250 """ 251 Generate code to instantiate an input from the result buffer, indexed with 252 `i`. Optionally add `suffix` to the input's name. 253 """ 254 raise NotImplementedError() 255 256 @staticmethod 257 def InstantiateInput(suffix = ""): 258 """ 259 Generate code to instantiate an input from the input buffer, indexed with 260 `i`. Optionally add `suffix` to the input's name. 261 """ 262 raise NotImplementedError() 263 264 @staticmethod 265 def InstantiateReference(suffix = ""): 266 """ 267 Generate code to instantiate an input from the reference buffer, indexed 268 with `i`. Optionally add `suffix` to the input's name. 269 """ 270 raise NotImplementedError() 271 272 @staticmethod 273 def Compare(left_suffix, operand, right_suffix): 274 """ 275 Generate code as a C++ expression comparing two inputs of this type. 276 """ 277 raise NotImplementedError() 278 279 280 class Scalar(Input): 281 """ 282 Base class for inputs that are represented as a single scalar value. 283 Subclasses should implement `TypeName()`, `Pri()` and `NDigit()` to specify 284 how they should be represented and printed, see the `U32` class for an 285 example. 286 """ 287 288 @staticmethod 289 def TypeName(): 290 """ 291 Return the type name as used to declare and instantiate this input. 292 """ 293 raise NotImplementedError() 294 295 @staticmethod 296 def Pri(): 297 """ 298 Return the format string used to generate a call to `printf` to print this 299 input type. For example, "PRIx32". 300 """ 301 raise NotImplementedError() 302 303 @staticmethod 304 def NDigit(): 305 """ 306 Return the number of digits to use to print this input type. 307 """ 308 raise NotImplementedError() 309 310 def Declare(self): 311 """ 312 A scalar input is declared as a single member in `struct Inputs`. 313 """ 314 return "{type_name} {name};".format(type_name=self.TypeName(), 315 name=self.name) 316 317 def PrintInput(self, suffix = ""): 318 code = "printf(\"0x%0{n_digit}\" {pri}, {name});" 319 return code.format(n_digit=self.NDigit(), pri=self.Pri(), 320 name=self.name + suffix) 321 322 def PrintOutput(self): 323 code = "printf(\"0x%0{n_digit}\" {pri}, results[i]->outputs[j].{name});" 324 return code.format(n_digit=self.NDigit(), pri=self.Pri(), name=self.name) 325 326 def InstantiateResult(self, suffix = ""): 327 code = "{type_name} {name}{suffix} = results[i]->outputs[j].{name};" 328 return code.format(type_name=self.TypeName(), name=self.name, suffix=suffix) 329 330 def InstantiateInput(self, suffix = ""): 331 code = "{type_name} {name}{suffix} = kTests[i].inputs[j].{name};" 332 return code.format(type_name=self.TypeName(), name=self.name, suffix=suffix) 333 334 def InstantiateReference(self, suffix = ""): 335 code = "{type_name} {name}{suffix} = reference[i].outputs[j].{name};" 336 return code.format(type_name=self.TypeName(), name=self.name, suffix=suffix) 337 338 def Compare(self, left_suffix, operand, right_suffix): 339 return """ 340 ({name}{left_suffix} {operand} {name}{right_suffix}) 341 """.format(name=self.name, left_suffix=left_suffix, operand=operand, 342 right_suffix=right_suffix) 343 344 345 class U32(Scalar): 346 """ 347 Base class for inputs that can be represented as 32 bit unsigned words. 348 """ 349 350 @staticmethod 351 def TypeName(): 352 return "uint32_t" 353 354 @staticmethod 355 def Pri(): 356 return "PRIx32" 357 358 @staticmethod 359 def NDigit(): 360 return 8 361 362 363 class Register(U32): 364 """ 365 Description of a Register input. The `Prologue` and `Epilogue` methods 366 describe what C++ code to emit to set and record the value of a register 367 before and after executing an instruction. 368 """ 369 370 def Prologue(self): 371 code = "__ Ldr({name}, MemOperand(input_ptr, offsetof(Inputs, {name})));" 372 return code.format(name=self.name) 373 374 def Epilogue(self): 375 code = "__ Str({name}, MemOperand(result_ptr, offsetof(Inputs, {name})));" 376 return code.format(name=self.name) 377 378 379 class NZCV(U32): 380 """ 381 Description of NZCV flags as inputs to an instruction. 382 383 The `Prologue` and `Epilogue` methods describe what C++ code to emit to set 384 and record the NZCV flags before and after emitting the instruction under 385 test. 386 """ 387 388 def Prologue(self): 389 # When setting the `NZCV` flags, we need to make sure we do not override the 390 # `Q` bit. Therefore we use two scratch registers that we push on the stack 391 # first to allow the instruction to use them as operands. 392 code = """{{ 393 UseScratchRegisterScope temp_registers(&masm); 394 Register nzcv_bits = temp_registers.Acquire(); 395 Register saved_q_bit = temp_registers.Acquire(); 396 // Save the `Q` bit flag. 397 __ Mrs(saved_q_bit, APSR); 398 __ And(saved_q_bit, saved_q_bit, QFlag); 399 // Set the `NZCV` and `Q` flags together. 400 __ Ldr(nzcv_bits, MemOperand(input_ptr, offsetof(Inputs, {}))); 401 __ Orr(nzcv_bits, nzcv_bits, saved_q_bit); 402 __ Msr(APSR_nzcvq, nzcv_bits); 403 }} 404 """ 405 return code.format(self.name) 406 407 def Epilogue(self): 408 code = """{{ 409 UseScratchRegisterScope temp_registers(&masm); 410 Register nzcv_bits = temp_registers.Acquire(); 411 __ Mrs(nzcv_bits, APSR); 412 // Only record the NZCV bits. 413 __ And(nzcv_bits, nzcv_bits, NZCVFlag); 414 __ Str(nzcv_bits, MemOperand(result_ptr, offsetof(Inputs, {}))); 415 }} 416 """ 417 return code.format(self.name) 418 419 420 class Q(U32): 421 """ 422 Description of the Q flag as inputs to an instruction. 423 424 The `Prologue` and `Epilogue` methods describe what C++ code to emit to set 425 and record the Q flag before and after emitting the instruction under test. 426 """ 427 428 def Prologue(self): 429 # When clearing or setting the `Q` bit, we need to make sure the `NZCV` 430 # flags are not overriden. Therefore we use two scratch registers that we 431 # push on the stack first to allow the instruction to use them as operands. 432 code = """{{ 433 UseScratchRegisterScope temp_registers(&masm); 434 Register q_bit = temp_registers.Acquire(); 435 Register saved_nzcv_bits = temp_registers.Acquire(); 436 // Save the `NZCV` flags. 437 __ Mrs(saved_nzcv_bits, APSR); 438 __ And(saved_nzcv_bits, saved_nzcv_bits, NZCVFlag); 439 // Set the `NZCV` and `Q` flags together. 440 __ Ldr(q_bit, MemOperand(input_ptr, offsetof(Inputs, {}))); 441 __ Orr(q_bit, q_bit, saved_nzcv_bits); 442 __ Msr(APSR_nzcvq, q_bit); 443 }} 444 """ 445 return code.format(self.name) 446 447 def Epilogue(self): 448 code = """{{ 449 UseScratchRegisterScope temp_registers(&masm); 450 Register q_bit = temp_registers.Acquire(); 451 __ Mrs(q_bit, APSR); 452 // Only record the Q bit. 453 __ And(q_bit, q_bit, QFlag); 454 __ Str(q_bit, MemOperand(result_ptr, offsetof(Inputs, {}))); 455 }} 456 """ 457 return code.format(self.name) 458 459 460 class GE(U32): 461 """ 462 Description of the GE flag as inputs to an instruction. 463 464 The `Prologue` and `Epilogue` methods describe what C++ code to emit to set 465 and record the GE flags before and after emitting the instruction under test. 466 """ 467 468 def Prologue(self): 469 # We need a scratch register to load the `GE` flags. It may alias a register 470 # used by the instruction so we save it on the stack. 471 code = """{{ 472 UseScratchRegisterScope temp_registers(&masm); 473 Register ge_bits = temp_registers.Acquire(); 474 __ Ldr(ge_bits, MemOperand(input_ptr, offsetof(Inputs, {}))); 475 __ Msr(APSR_g, ge_bits); 476 }} 477 """ 478 return code.format(self.name) 479 480 def Epilogue(self): 481 code = """{{ 482 UseScratchRegisterScope temp_registers(&masm); 483 Register ge_bits = temp_registers.Acquire(); 484 __ Mrs(ge_bits, APSR); 485 // Only record the GE bits. 486 __ And(ge_bits, ge_bits, GEFlags); 487 __ Str(ge_bits, MemOperand(result_ptr, offsetof(Inputs, {}))); 488 }} 489 """ 490 return code.format(self.name) 491 492 493 class MemOperand(Input): 494 """ 495 Description of a memory location input, used to test a `MemOperand` operand. 496 497 A memory location input is a compound type and is represented as an 498 array of two `uint32_t` values, an "offset" and a "data": 499 500 ~~~ 501 { 502 0x0, // Offset used to record the base register in case it was 503 // updated. 504 0xabababab // 32 bit value in memory the instruction should work with. 505 } 506 ~~~ 507 """ 508 509 def Declare(self): 510 """ 511 Declare the input as a two element array. 512 """ 513 return "uint32_t {name}[2];".format(name=self.name) 514 515 def PrintInput(self, suffix = ""): 516 code = '''printf("{{0x%08" PRIx32 ", 0x%08" PRIx32 "}}", 517 {name}[0], {name}[1]);''' 518 return code.format(name=self.name + suffix) 519 520 def PrintOutput(self): 521 code = '''printf("{{0x%08" PRIx32 ", 0x%08" PRIx32 "}}", 522 results[i]->outputs[j].{name}[0], 523 results[i]->outputs[j].{name}[1]);''' 524 return code.format(name=self.name) 525 526 def InstantiateResult(self, suffix = ""): 527 code = """uint32_t {name}{suffix}[2] = {{ 528 results[i]->outputs[j].{name}[0], 529 results[i]->outputs[j].{name}[1] 530 }}; 531 """ 532 return code.format(name=self.name, suffix=suffix) 533 534 def InstantiateInput(self, suffix = ""): 535 code = """uint32_t {name}{suffix}[2] = {{ 536 kTests[i].inputs[j].{name}[0], 537 kTests[i].inputs[j].{name}[1] 538 }}; 539 """ 540 return code.format(name=self.name, suffix=suffix) 541 542 def InstantiateReference(self, suffix = ""): 543 code = """uint32_t {name}{suffix}[2] = {{ 544 results[i]->outputs[j].{name}[0], 545 results[i]->outputs[j].{name}[1] 546 }}; 547 """ 548 return code.format(name=self.name, suffix=suffix) 549 550 def Compare(self, left_suffix, operand, right_suffix): 551 return """ 552 (({name}{left_suffix}[0] {operand} {name}{right_suffix}[0]) && 553 ({name}{left_suffix}[1] {operand} {name}{right_suffix}[1])) 554 """.format(name=self.name, left_suffix=left_suffix, operand=operand, 555 right_suffix=right_suffix) 556 557 def Prologue(self): 558 return """ 559 // Allocate 4 bytes for the instruction to work with. 560 scratch_memory_buffers[i] = new byte[4]; 561 {{ 562 UseScratchRegisterScope temp_registers(&masm); 563 564 Register {name}_tmp = temp_registers.Acquire(); 565 Register base_register = {name}.GetBaseRegister(); 566 567 // Write the expected data into the scratch buffer. 568 __ Mov(base_register, Operand::From(scratch_memory_buffers[i])); 569 __ Ldr({name}_tmp, MemOperand(input_ptr, offsetof(Inputs, {name}) + 4)); 570 __ Str({name}_tmp, MemOperand(base_register)); 571 572 // Compute the address to put into the base register so that the 573 // `MemOperand` points to the right location. 574 // TODO: Support more kinds of `MemOperand`. 575 if (!{name}.IsPostIndex()) {{ 576 if ({name}.IsImmediate()) {{ 577 if ({name}.GetSign().IsPlus()) {{ 578 __ Mov({name}_tmp, {name}.GetOffsetImmediate()); 579 __ Sub(base_register, base_register, {name}_tmp); 580 }} else {{ 581 __ Mov({name}_tmp, -{name}.GetOffsetImmediate()); 582 __ Add(base_register, base_register, {name}_tmp); 583 }} 584 }} else if ({name}.IsShiftedRegister()) {{ 585 __ Mov({name}_tmp, Operand({name}.GetOffsetRegister(), 586 {name}.GetShift(), 587 {name}.GetShiftAmount())); 588 if ({name}.GetSign().IsPlus()) {{ 589 __ Sub(base_register, base_register, {name}_tmp); 590 }} else {{ 591 __ Add(base_register, base_register, {name}_tmp); 592 }} 593 }} 594 }} 595 }} 596 """.format(name=self.name) 597 598 def Epilogue(self): 599 # TODO: This generated code does not support recording the state for 600 # instructions where the base register is the same as another register used 601 # in the instruction. It is possible to do so but requires more temporary 602 # registers which is not trivial to implement without 603 # `UseScratchRegisterScope`. We will be able to lift this restriction when 604 # it is implemented. 605 return """{{ 606 UseScratchRegisterScope temp_registers(&masm); 607 Register {name}_tmp = temp_registers.Acquire(); 608 Register base_register = {name}.GetBaseRegister(); 609 610 // Compute the address of the scratch buffer by from the base register. If 611 // the instruction has updated the base register, we will be able to 612 // record it. 613 if (!{name}.IsPostIndex()) {{ 614 if ({name}.IsImmediate()) {{ 615 if ({name}.GetSign().IsPlus()) {{ 616 __ Mov({name}_tmp, {name}.GetOffsetImmediate()); 617 __ Add(base_register, base_register, {name}_tmp); 618 }} else {{ 619 __ Mov({name}_tmp, -{name}.GetOffsetImmediate()); 620 __ Sub(base_register, base_register, {name}_tmp); 621 }} 622 }} else if ({name}.IsShiftedRegister()) {{ 623 __ Mov({name}_tmp, Operand({name}.GetOffsetRegister(), 624 {name}.GetShift(), 625 {name}.GetShiftAmount())); 626 if ({name}.GetSign().IsPlus()) {{ 627 __ Add(base_register, base_register, {name}_tmp); 628 }} else {{ 629 __ Sub(base_register, base_register, {name}_tmp); 630 }} 631 }} 632 }} 633 634 // Record the value of the base register, as an offset from the scratch 635 // buffer's address. 636 __ Mov({name}_tmp, Operand::From(scratch_memory_buffers[i])); 637 __ Sub(base_register, base_register, {name}_tmp); 638 __ Str(base_register, MemOperand(result_ptr, offsetof(Inputs, {name}))); 639 640 // Record the 32 bit word from memory. 641 __ Ldr({name}_tmp, MemOperand({name}_tmp)); 642 __ Str({name}_tmp, MemOperand(result_ptr, offsetof(Inputs, {name}) + 4)); 643 }} 644 """.format(name=self.name) 645