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 27class 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 79class 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 126class 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 186class 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 280class 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 345class 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 363class F64(Scalar): 364 @staticmethod 365 def TypeName(): 366 return "uint64_t" 367 368 @staticmethod 369 def Pri(): 370 return "PRIx64" 371 372 @staticmethod 373 def NDigit(): 374 return 16 375 376 def PrintInput(self, suffix = ""): 377 code = "printf(\"0x%0{n_digit}\" {pri} \"(%g)\", {name}, RawbitsToDouble({name}));" 378 return code.format(n_digit=self.NDigit(), pri=self.Pri(), 379 name=self.name + suffix) 380 381 382class Register(U32): 383 """ 384 Description of a Register input. The `Prologue` and `Epilogue` methods 385 describe what C++ code to emit to set and record the value of a register 386 before and after executing an instruction. 387 """ 388 389 def Prologue(self): 390 code = "__ Ldr({name}, MemOperand(input_ptr, offsetof(Inputs, {name})));" 391 return code.format(name=self.name) 392 393 def Epilogue(self): 394 code = "__ Str({name}, MemOperand(result_ptr, offsetof(Inputs, {name})));" 395 return code.format(name=self.name) 396 397 398class DRegisterF64(F64): 399 def Prologue(self): 400 code = "__ Vldr({name}, MemOperand(input_ptr, offsetof(Inputs, {name})));" 401 return code.format(name=self.name) 402 403 def Epilogue(self): 404 code = "__ Vstr({name}, MemOperand(result_ptr, offsetof(Inputs, {name})));" 405 return code.format(name=self.name) 406 407 408class NZCV(U32): 409 """ 410 Description of NZCV flags as inputs to an instruction. 411 412 The `Prologue` and `Epilogue` methods describe what C++ code to emit to set 413 and record the NZCV flags before and after emitting the instruction under 414 test. 415 """ 416 417 def Prologue(self): 418 # When setting the `NZCV` flags, we need to make sure we do not override the 419 # `Q` bit. Therefore we use two scratch registers that we push on the stack 420 # first to allow the instruction to use them as operands. 421 code = """{{ 422 UseScratchRegisterScope temp_registers(&masm); 423 Register nzcv_bits = temp_registers.Acquire(); 424 Register saved_q_bit = temp_registers.Acquire(); 425 // Save the `Q` bit flag. 426 __ Mrs(saved_q_bit, APSR); 427 __ And(saved_q_bit, saved_q_bit, QFlag); 428 // Set the `NZCV` and `Q` flags together. 429 __ Ldr(nzcv_bits, MemOperand(input_ptr, offsetof(Inputs, {}))); 430 __ Orr(nzcv_bits, nzcv_bits, saved_q_bit); 431 __ Msr(APSR_nzcvq, nzcv_bits); 432 }} 433 """ 434 return code.format(self.name) 435 436 def Epilogue(self): 437 code = """{{ 438 UseScratchRegisterScope temp_registers(&masm); 439 Register nzcv_bits = temp_registers.Acquire(); 440 __ Mrs(nzcv_bits, APSR); 441 // Only record the NZCV bits. 442 __ And(nzcv_bits, nzcv_bits, NZCVFlag); 443 __ Str(nzcv_bits, MemOperand(result_ptr, offsetof(Inputs, {}))); 444 }} 445 """ 446 return code.format(self.name) 447 448 449class Q(U32): 450 """ 451 Description of the Q flag as inputs to an instruction. 452 453 The `Prologue` and `Epilogue` methods describe what C++ code to emit to set 454 and record the Q flag before and after emitting the instruction under test. 455 """ 456 457 def Prologue(self): 458 # When clearing or setting the `Q` bit, we need to make sure the `NZCV` 459 # flags are not overriden. Therefore we use two scratch registers that we 460 # push on the stack first to allow the instruction to use them as operands. 461 code = """{{ 462 UseScratchRegisterScope temp_registers(&masm); 463 Register q_bit = temp_registers.Acquire(); 464 Register saved_nzcv_bits = temp_registers.Acquire(); 465 // Save the `NZCV` flags. 466 __ Mrs(saved_nzcv_bits, APSR); 467 __ And(saved_nzcv_bits, saved_nzcv_bits, NZCVFlag); 468 // Set the `NZCV` and `Q` flags together. 469 __ Ldr(q_bit, MemOperand(input_ptr, offsetof(Inputs, {}))); 470 __ Orr(q_bit, q_bit, saved_nzcv_bits); 471 __ Msr(APSR_nzcvq, q_bit); 472 }} 473 """ 474 return code.format(self.name) 475 476 def Epilogue(self): 477 code = """{{ 478 UseScratchRegisterScope temp_registers(&masm); 479 Register q_bit = temp_registers.Acquire(); 480 __ Mrs(q_bit, APSR); 481 // Only record the Q bit. 482 __ And(q_bit, q_bit, QFlag); 483 __ Str(q_bit, MemOperand(result_ptr, offsetof(Inputs, {}))); 484 }} 485 """ 486 return code.format(self.name) 487 488 489class GE(U32): 490 """ 491 Description of the GE flag as inputs to an instruction. 492 493 The `Prologue` and `Epilogue` methods describe what C++ code to emit to set 494 and record the GE flags before and after emitting the instruction under test. 495 """ 496 497 def Prologue(self): 498 # We need a scratch register to load the `GE` flags. 499 code = """{{ 500 UseScratchRegisterScope temp_registers(&masm); 501 Register ge_bits = temp_registers.Acquire(); 502 __ Ldr(ge_bits, MemOperand(input_ptr, offsetof(Inputs, {}))); 503 __ Msr(APSR_g, ge_bits); 504 }} 505 """ 506 return code.format(self.name) 507 508 def Epilogue(self): 509 code = """{{ 510 UseScratchRegisterScope temp_registers(&masm); 511 Register ge_bits = temp_registers.Acquire(); 512 __ Mrs(ge_bits, APSR); 513 // Only record the GE bits. 514 __ And(ge_bits, ge_bits, GEFlags); 515 __ Str(ge_bits, MemOperand(result_ptr, offsetof(Inputs, {}))); 516 }} 517 """ 518 return code.format(self.name) 519 520 521class FPSCR(U32): 522 def Prologue(self): 523 # We need a scratch register to load the `FPCSR` flags. 524 code = """{{ 525 UseScratchRegisterScope temp_registers(&masm); 526 Register fpsr_bits = temp_registers.Acquire(); 527 __ Ldr(fpsr_bits, MemOperand(input_ptr, offsetof(Inputs, {}))); 528 __ Vmsr(FPSCR, fpsr_bits); 529 }} 530 """ 531 return code.format(self.name) 532 533 def Epilogue(self): 534 code = """{{ 535 UseScratchRegisterScope temp_registers(&masm); 536 Register fpsr_bits = temp_registers.Acquire(); 537 __ Vmrs(RegisterOrAPSR_nzcv(fpsr_bits.GetCode()), FPSCR); 538 __ Str(fpsr_bits, MemOperand(result_ptr, offsetof(Inputs, {}))); 539 }} 540 """ 541 return code.format(self.name) 542 543 544class MemOperand(Input): 545 """ 546 Description of a memory location input, used to test a `MemOperand` operand. 547 548 A memory location input is a compound type and is represented as an 549 array of two `uint32_t` values, an "offset" and a "data": 550 551 ~~~ 552 { 553 0x0, // Offset used to record the base register in case it was 554 // updated. 555 0xabababab // 32 bit value in memory the instruction should work with. 556 } 557 ~~~ 558 """ 559 560 def Declare(self): 561 """ 562 Declare the input as a two element array. 563 """ 564 return "uint32_t {name}[2];".format(name=self.name) 565 566 def PrintInput(self, suffix = ""): 567 code = '''printf("{{0x%08" PRIx32 ", 0x%08" PRIx32 "}}", 568 {name}[0], {name}[1]);''' 569 return code.format(name=self.name + suffix) 570 571 def PrintOutput(self): 572 code = '''printf("{{0x%08" PRIx32 ", 0x%08" PRIx32 "}}", 573 results[i]->outputs[j].{name}[0], 574 results[i]->outputs[j].{name}[1]);''' 575 return code.format(name=self.name) 576 577 def InstantiateResult(self, suffix = ""): 578 code = """uint32_t {name}{suffix}[2] = {{ 579 results[i]->outputs[j].{name}[0], 580 results[i]->outputs[j].{name}[1] 581 }}; 582 """ 583 return code.format(name=self.name, suffix=suffix) 584 585 def InstantiateInput(self, suffix = ""): 586 code = """uint32_t {name}{suffix}[2] = {{ 587 kTests[i].inputs[j].{name}[0], 588 kTests[i].inputs[j].{name}[1] 589 }}; 590 """ 591 return code.format(name=self.name, suffix=suffix) 592 593 def InstantiateReference(self, suffix = ""): 594 code = """uint32_t {name}{suffix}[2] = {{ 595 results[i]->outputs[j].{name}[0], 596 results[i]->outputs[j].{name}[1] 597 }}; 598 """ 599 return code.format(name=self.name, suffix=suffix) 600 601 def Compare(self, left_suffix, operand, right_suffix): 602 return """ 603 (({name}{left_suffix}[0] {operand} {name}{right_suffix}[0]) && 604 ({name}{left_suffix}[1] {operand} {name}{right_suffix}[1])) 605 """.format(name=self.name, left_suffix=left_suffix, operand=operand, 606 right_suffix=right_suffix) 607 608 def Prologue(self): 609 return """ 610 // Allocate 4 bytes for the instruction to work with. 611 scratch_memory_buffers[i] = new byte[4]; 612 {{ 613 UseScratchRegisterScope temp_registers(&masm); 614 615 Register {name}_tmp = temp_registers.Acquire(); 616 Register base_register = {name}.GetBaseRegister(); 617 618 // Write the expected data into the scratch buffer. 619 __ Mov(base_register, Operand::From(scratch_memory_buffers[i])); 620 __ Ldr({name}_tmp, MemOperand(input_ptr, offsetof(Inputs, {name}) + 4)); 621 __ Str({name}_tmp, MemOperand(base_register)); 622 623 // Compute the address to put into the base register so that the 624 // `MemOperand` points to the right location. 625 // TODO: Support more kinds of `MemOperand`. 626 if (!{name}.IsPostIndex()) {{ 627 if ({name}.IsImmediate()) {{ 628 if ({name}.GetSign().IsPlus()) {{ 629 __ Mov({name}_tmp, {name}.GetOffsetImmediate()); 630 __ Sub(base_register, base_register, {name}_tmp); 631 }} else {{ 632 __ Mov({name}_tmp, -{name}.GetOffsetImmediate()); 633 __ Add(base_register, base_register, {name}_tmp); 634 }} 635 }} else if ({name}.IsShiftedRegister()) {{ 636 __ Mov({name}_tmp, Operand({name}.GetOffsetRegister(), 637 {name}.GetShift(), 638 {name}.GetShiftAmount())); 639 if ({name}.GetSign().IsPlus()) {{ 640 __ Sub(base_register, base_register, {name}_tmp); 641 }} else {{ 642 __ Add(base_register, base_register, {name}_tmp); 643 }} 644 }} 645 }} 646 }} 647 """.format(name=self.name) 648 649 def Epilogue(self): 650 # TODO: This generated code does not support recording the state for 651 # instructions where the base register is the same as another register used 652 # in the instruction. It is possible to do so but requires more temporary 653 # registers which is not trivial to implement without 654 # `UseScratchRegisterScope`. We will be able to lift this restriction when 655 # it is implemented. 656 return """{{ 657 UseScratchRegisterScope temp_registers(&masm); 658 Register {name}_tmp = temp_registers.Acquire(); 659 Register base_register = {name}.GetBaseRegister(); 660 661 // Compute the address of the scratch buffer by from the base register. If 662 // the instruction has updated the base register, we will be able to 663 // record it. 664 if (!{name}.IsPostIndex()) {{ 665 if ({name}.IsImmediate()) {{ 666 if ({name}.GetSign().IsPlus()) {{ 667 __ Mov({name}_tmp, {name}.GetOffsetImmediate()); 668 __ Add(base_register, base_register, {name}_tmp); 669 }} else {{ 670 __ Mov({name}_tmp, -{name}.GetOffsetImmediate()); 671 __ Sub(base_register, base_register, {name}_tmp); 672 }} 673 }} else if ({name}.IsShiftedRegister()) {{ 674 __ Mov({name}_tmp, Operand({name}.GetOffsetRegister(), 675 {name}.GetShift(), 676 {name}.GetShiftAmount())); 677 if ({name}.GetSign().IsPlus()) {{ 678 __ Add(base_register, base_register, {name}_tmp); 679 }} else {{ 680 __ Sub(base_register, base_register, {name}_tmp); 681 }} 682 }} 683 }} 684 685 // Record the value of the base register, as an offset from the scratch 686 // buffer's address. 687 __ Mov({name}_tmp, Operand::From(scratch_memory_buffers[i])); 688 __ Sub(base_register, base_register, {name}_tmp); 689 __ Str(base_register, MemOperand(result_ptr, offsetof(Inputs, {name}))); 690 691 // Record the 32 bit word from memory. 692 __ Ldr({name}_tmp, MemOperand({name}_tmp)); 693 __ Str({name}_tmp, MemOperand(result_ptr, offsetof(Inputs, {name}) + 4)); 694 }} 695 """.format(name=self.name) 696