Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 33 // The original source code covered by the above license above has been | 33 // The original source code covered by the above license above has been |
| 34 // modified significantly by Google Inc. | 34 // modified significantly by Google Inc. |
| 35 // Copyright 2010 the V8 project authors. All rights reserved. | 35 // Copyright 2010 the V8 project authors. All rights reserved. |
| 36 | 36 |
| 37 // A light-weight ARM Assembler | 37 // A light-weight ARM Assembler |
| 38 // Generates user mode instructions for the ARM architecture up to version 5 | 38 // Generates user mode instructions for the ARM architecture up to version 5 |
| 39 | 39 |
| 40 #ifndef V8_ARM_ASSEMBLER_ARM_H_ | 40 #ifndef V8_ARM_ASSEMBLER_ARM_H_ |
| 41 #define V8_ARM_ASSEMBLER_ARM_H_ | 41 #define V8_ARM_ASSEMBLER_ARM_H_ |
| 42 #include <stdio.h> | 42 #include <stdio.h> |
| 43 #include "constants-arm.h" | |
|
Mads Ager (chromium)
2011/01/20 12:40:00
Can we keep the include list alphabeticed?
Alexandre
2011/01/21 16:22:15
Done.
| |
| 43 #include "assembler.h" | 44 #include "assembler.h" |
| 44 #include "serialize.h" | 45 #include "serialize.h" |
| 45 | 46 |
| 47 using namespace assembler::arm; | |
|
Mads Ager (chromium)
2011/01/20 12:40:00
We are not using 'using' directives. Have a look a
Alexandre
2011/01/21 16:22:15
Removed. We don't need it anymore as the assembler
| |
| 48 | |
| 46 namespace v8 { | 49 namespace v8 { |
| 47 namespace internal { | 50 namespace internal { |
| 48 | 51 |
| 49 // CPU Registers. | 52 // CPU Registers. |
| 50 // | 53 // |
| 51 // 1) We would prefer to use an enum, but enum values are assignment- | 54 // 1) We would prefer to use an enum, but enum values are assignment- |
| 52 // compatible with int, which has caused code-generation bugs. | 55 // compatible with int, which has caused code-generation bugs. |
| 53 // | 56 // |
| 54 // 2) We would prefer to use a class instead of a struct but we don't like | 57 // 2) We would prefer to use a class instead of a struct but we don't like |
| 55 // the register initialization to depend on the particular initialization | 58 // the register initialization to depend on the particular initialization |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 293 const DwVfpRegister d7 = { 7 }; | 296 const DwVfpRegister d7 = { 7 }; |
| 294 const DwVfpRegister d8 = { 8 }; | 297 const DwVfpRegister d8 = { 8 }; |
| 295 const DwVfpRegister d9 = { 9 }; | 298 const DwVfpRegister d9 = { 9 }; |
| 296 const DwVfpRegister d10 = { 10 }; | 299 const DwVfpRegister d10 = { 10 }; |
| 297 const DwVfpRegister d11 = { 11 }; | 300 const DwVfpRegister d11 = { 11 }; |
| 298 const DwVfpRegister d12 = { 12 }; | 301 const DwVfpRegister d12 = { 12 }; |
| 299 const DwVfpRegister d13 = { 13 }; | 302 const DwVfpRegister d13 = { 13 }; |
| 300 const DwVfpRegister d14 = { 14 }; | 303 const DwVfpRegister d14 = { 14 }; |
| 301 const DwVfpRegister d15 = { 15 }; | 304 const DwVfpRegister d15 = { 15 }; |
| 302 | 305 |
| 303 // VFP FPSCR constants. | |
| 304 static const uint32_t kVFPNConditionFlagBit = 1 << 31; | |
| 305 static const uint32_t kVFPZConditionFlagBit = 1 << 30; | |
| 306 static const uint32_t kVFPCConditionFlagBit = 1 << 29; | |
| 307 static const uint32_t kVFPVConditionFlagBit = 1 << 28; | |
| 308 | |
| 309 static const uint32_t kVFPFlushToZeroMask = 1 << 24; | |
| 310 | |
| 311 static const uint32_t kVFPRoundingModeMask = 3 << 22; | |
| 312 static const uint32_t kVFPRoundToMinusInfinityBits = 2 << 22; | |
| 313 | |
| 314 static const uint32_t kVFPExceptionMask = 0xf; | |
| 315 | 306 |
| 316 // Coprocessor register | 307 // Coprocessor register |
| 317 struct CRegister { | 308 struct CRegister { |
| 318 bool is_valid() const { return 0 <= code_ && code_ < 16; } | 309 bool is_valid() const { return 0 <= code_ && code_ < 16; } |
| 319 bool is(CRegister creg) const { return code_ == creg.code_; } | 310 bool is(CRegister creg) const { return code_ == creg.code_; } |
| 320 int code() const { | 311 int code() const { |
| 321 ASSERT(is_valid()); | 312 ASSERT(is_valid()); |
| 322 return code_; | 313 return code_; |
| 323 } | 314 } |
| 324 int bit() const { | 315 int bit() const { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 p9 = 9, | 356 p9 = 9, |
| 366 p10 = 10, | 357 p10 = 10, |
| 367 p11 = 11, | 358 p11 = 11, |
| 368 p12 = 12, | 359 p12 = 12, |
| 369 p13 = 13, | 360 p13 = 13, |
| 370 p14 = 14, | 361 p14 = 14, |
| 371 p15 = 15 | 362 p15 = 15 |
| 372 }; | 363 }; |
| 373 | 364 |
| 374 | 365 |
| 375 // Condition field in instructions. | |
| 376 enum Condition { | |
| 377 // any value < 0 is considered no_condition | |
| 378 no_condition = -1, | |
| 379 | |
| 380 eq = 0 << 28, // Z set equal. | |
| 381 ne = 1 << 28, // Z clear not equal. | |
| 382 nz = 1 << 28, // Z clear not zero. | |
| 383 cs = 2 << 28, // C set carry set. | |
| 384 hs = 2 << 28, // C set unsigned higher or same. | |
| 385 cc = 3 << 28, // C clear carry clear. | |
| 386 lo = 3 << 28, // C clear unsigned lower. | |
| 387 mi = 4 << 28, // N set negative. | |
| 388 pl = 5 << 28, // N clear positive or zero. | |
| 389 vs = 6 << 28, // V set overflow. | |
| 390 vc = 7 << 28, // V clear no overflow. | |
| 391 hi = 8 << 28, // C set, Z clear unsigned higher. | |
| 392 ls = 9 << 28, // C clear or Z set unsigned lower or same. | |
| 393 ge = 10 << 28, // N == V greater or equal. | |
| 394 lt = 11 << 28, // N != V less than. | |
| 395 gt = 12 << 28, // Z clear, N == V greater than. | |
| 396 le = 13 << 28, // Z set or N != V less then or equal | |
| 397 al = 14 << 28 // always. | |
| 398 }; | |
| 399 | |
| 400 | |
| 401 // Returns the equivalent of !cc. | |
| 402 inline Condition NegateCondition(Condition cc) { | |
| 403 ASSERT(cc != al); | |
| 404 return static_cast<Condition>(cc ^ ne); | |
| 405 } | |
| 406 | |
| 407 | |
| 408 // Corresponds to transposing the operands of a comparison. | |
| 409 inline Condition ReverseCondition(Condition cc) { | |
| 410 switch (cc) { | |
| 411 case lo: | |
| 412 return hi; | |
| 413 case hi: | |
| 414 return lo; | |
| 415 case hs: | |
| 416 return ls; | |
| 417 case ls: | |
| 418 return hs; | |
| 419 case lt: | |
| 420 return gt; | |
| 421 case gt: | |
| 422 return lt; | |
| 423 case ge: | |
| 424 return le; | |
| 425 case le: | |
| 426 return ge; | |
| 427 default: | |
| 428 return cc; | |
| 429 }; | |
| 430 } | |
| 431 | |
| 432 | |
| 433 // Branch hints are not used on the ARM. They are defined so that they can | |
| 434 // appear in shared function signatures, but will be ignored in ARM | |
| 435 // implementations. | |
| 436 enum Hint { no_hint }; | |
| 437 | |
| 438 // Hints are not used on the arm. Negating is trivial. | |
| 439 inline Hint NegateHint(Hint ignored) { return no_hint; } | |
| 440 | |
| 441 | |
| 442 // ----------------------------------------------------------------------------- | |
| 443 // Addressing modes and instruction variants | |
| 444 | |
| 445 // Shifter operand shift operation | |
| 446 enum ShiftOp { | |
| 447 LSL = 0 << 5, | |
| 448 LSR = 1 << 5, | |
| 449 ASR = 2 << 5, | |
| 450 ROR = 3 << 5, | |
| 451 RRX = -1 | |
| 452 }; | |
| 453 | |
| 454 | |
| 455 // Condition code updating mode | |
| 456 enum SBit { | |
| 457 SetCC = 1 << 20, // set condition code | |
| 458 LeaveCC = 0 << 20 // leave condition code unchanged | |
| 459 }; | |
| 460 | |
| 461 | |
| 462 // Status register selection | |
| 463 enum SRegister { | |
| 464 CPSR = 0 << 22, | |
| 465 SPSR = 1 << 22 | |
| 466 }; | |
| 467 | |
| 468 | |
| 469 // Status register fields | |
| 470 enum SRegisterField { | |
| 471 CPSR_c = CPSR | 1 << 16, | |
| 472 CPSR_x = CPSR | 1 << 17, | |
| 473 CPSR_s = CPSR | 1 << 18, | |
| 474 CPSR_f = CPSR | 1 << 19, | |
| 475 SPSR_c = SPSR | 1 << 16, | |
| 476 SPSR_x = SPSR | 1 << 17, | |
| 477 SPSR_s = SPSR | 1 << 18, | |
| 478 SPSR_f = SPSR | 1 << 19 | |
| 479 }; | |
| 480 | |
| 481 // Status register field mask (or'ed SRegisterField enum values) | |
| 482 typedef uint32_t SRegisterFieldMask; | |
| 483 | |
| 484 | |
| 485 // Memory operand addressing mode | |
| 486 enum AddrMode { | |
| 487 // bit encoding P U W | |
| 488 Offset = (8|4|0) << 21, // offset (without writeback to base) | |
| 489 PreIndex = (8|4|1) << 21, // pre-indexed addressing with writeback | |
| 490 PostIndex = (0|4|0) << 21, // post-indexed addressing with writeback | |
| 491 NegOffset = (8|0|0) << 21, // negative offset (without writeback to base) | |
| 492 NegPreIndex = (8|0|1) << 21, // negative pre-indexed with writeback | |
| 493 NegPostIndex = (0|0|0) << 21 // negative post-indexed with writeback | |
| 494 }; | |
| 495 | |
| 496 | |
| 497 // Load/store multiple addressing mode | |
| 498 enum BlockAddrMode { | |
| 499 // bit encoding P U W | |
| 500 da = (0|0|0) << 21, // decrement after | |
| 501 ia = (0|4|0) << 21, // increment after | |
| 502 db = (8|0|0) << 21, // decrement before | |
| 503 ib = (8|4|0) << 21, // increment before | |
| 504 da_w = (0|0|1) << 21, // decrement after with writeback to base | |
| 505 ia_w = (0|4|1) << 21, // increment after with writeback to base | |
| 506 db_w = (8|0|1) << 21, // decrement before with writeback to base | |
| 507 ib_w = (8|4|1) << 21 // increment before with writeback to base | |
| 508 }; | |
| 509 | |
| 510 | |
| 511 // Coprocessor load/store operand size | |
| 512 enum LFlag { | |
| 513 Long = 1 << 22, // long load/store coprocessor | |
| 514 Short = 0 << 22 // short load/store coprocessor | |
| 515 }; | |
| 516 | |
| 517 | |
| 518 // ----------------------------------------------------------------------------- | 366 // ----------------------------------------------------------------------------- |
| 519 // Machine instruction Operands | 367 // Machine instruction Operands |
| 520 | 368 |
| 521 // Class Operand represents a shifter operand in data processing instructions | 369 // Class Operand represents a shifter operand in data processing instructions |
| 522 class Operand BASE_EMBEDDED { | 370 class Operand BASE_EMBEDDED { |
| 523 public: | 371 public: |
| 524 // immediate | 372 // immediate |
| 525 INLINE(explicit Operand(int32_t immediate, | 373 INLINE(explicit Operand(int32_t immediate, |
| 526 RelocInfo::Mode rmode = RelocInfo::NONE)); | 374 RelocInfo::Mode rmode = RelocInfo::NONE)); |
| 527 INLINE(explicit Operand(const ExternalReference& f)); | 375 INLINE(explicit Operand(const ExternalReference& f)); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 651 #endif | 499 #endif |
| 652 }; | 500 }; |
| 653 | 501 |
| 654 private: | 502 private: |
| 655 static unsigned supported_; | 503 static unsigned supported_; |
| 656 static unsigned enabled_; | 504 static unsigned enabled_; |
| 657 static unsigned found_by_runtime_probing_; | 505 static unsigned found_by_runtime_probing_; |
| 658 }; | 506 }; |
| 659 | 507 |
| 660 | 508 |
| 661 typedef int32_t Instr; | |
| 662 | |
| 663 | |
| 664 extern const Instr kMovLrPc; | 509 extern const Instr kMovLrPc; |
| 665 extern const Instr kLdrPCMask; | 510 extern const Instr kLdrPCMask; |
| 666 extern const Instr kLdrPCPattern; | 511 extern const Instr kLdrPCPattern; |
| 667 extern const Instr kBlxRegMask; | 512 extern const Instr kBlxRegMask; |
| 668 extern const Instr kBlxRegPattern; | 513 extern const Instr kBlxRegPattern; |
| 669 | 514 |
| 670 extern const Instr kMovMvnMask; | 515 extern const Instr kMovMvnMask; |
| 671 extern const Instr kMovMvnPattern; | 516 extern const Instr kMovMvnPattern; |
| 672 extern const Instr kMovMvnFlip; | 517 extern const Instr kMovMvnFlip; |
| 673 | 518 |
| 674 extern const Instr kMovLeaveCCMask; | 519 extern const Instr kMovLeaveCCMask; |
| 675 extern const Instr kMovLeaveCCPattern; | 520 extern const Instr kMovLeaveCCPattern; |
| 676 extern const Instr kMovwMask; | 521 extern const Instr kMovwMask; |
| 677 extern const Instr kMovwPattern; | 522 extern const Instr kMovwPattern; |
| 678 extern const Instr kMovwLeaveCCFlip; | 523 extern const Instr kMovwLeaveCCFlip; |
| 679 | 524 |
| 680 extern const Instr kCmpCmnMask; | 525 extern const Instr kCmpCmnMask; |
| 681 extern const Instr kCmpCmnPattern; | 526 extern const Instr kCmpCmnPattern; |
| 682 extern const Instr kCmpCmnFlip; | 527 extern const Instr kCmpCmnFlip; |
| 683 | |
| 684 extern const Instr kALUMask; | |
| 685 extern const Instr kAddPattern; | |
| 686 extern const Instr kSubPattern; | |
| 687 extern const Instr kAndPattern; | |
| 688 extern const Instr kBicPattern; | |
| 689 extern const Instr kAddSubFlip; | 528 extern const Instr kAddSubFlip; |
| 690 extern const Instr kAndBicFlip; | 529 extern const Instr kAndBicFlip; |
| 691 | 530 |
| 531 | |
| 532 | |
| 692 class Assembler : public Malloced { | 533 class Assembler : public Malloced { |
| 693 public: | 534 public: |
| 694 // Create an assembler. Instructions and relocation information are emitted | 535 // Create an assembler. Instructions and relocation information are emitted |
| 695 // into a buffer, with the instructions starting from the beginning and the | 536 // into a buffer, with the instructions starting from the beginning and the |
| 696 // relocation information starting from the end of the buffer. See CodeDesc | 537 // relocation information starting from the end of the buffer. See CodeDesc |
| 697 // for a detailed comment on the layout (globals.h). | 538 // for a detailed comment on the layout (globals.h). |
| 698 // | 539 // |
| 699 // If the provided buffer is NULL, the assembler allocates and grows its own | 540 // If the provided buffer is NULL, the assembler allocates and grows its own |
| 700 // buffer, and buffer_size determines the initial buffer size. The buffer is | 541 // buffer, and buffer_size determines the initial buffer size. The buffer is |
| 701 // owned by the assembler and deallocated upon destruction of the assembler. | 542 // owned by the assembler and deallocated upon destruction of the assembler. |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 994 const MemOperand& src, Condition cond = al); | 835 const MemOperand& src, Condition cond = al); |
| 995 void strd(Register src1, | 836 void strd(Register src1, |
| 996 Register src2, | 837 Register src2, |
| 997 const MemOperand& dst, Condition cond = al); | 838 const MemOperand& dst, Condition cond = al); |
| 998 | 839 |
| 999 // Load/Store multiple instructions | 840 // Load/Store multiple instructions |
| 1000 void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al); | 841 void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al); |
| 1001 void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al); | 842 void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al); |
| 1002 | 843 |
| 1003 // Exception-generating instructions and debugging support | 844 // Exception-generating instructions and debugging support |
| 1004 static const int kDefaultStopCode = -1; | |
| 1005 void stop(const char* msg, | 845 void stop(const char* msg, |
| 1006 Condition cond = al, | 846 Condition cond = al, |
| 1007 int32_t code = kDefaultStopCode); | 847 int32_t code = kDefaultStopCode); |
| 1008 | 848 |
| 1009 void bkpt(uint32_t imm16); // v5 and above | 849 void bkpt(uint32_t imm16); // v5 and above |
| 1010 void svc(uint32_t imm24, Condition cond = al); | 850 void svc(uint32_t imm24, Condition cond = al); |
| 1011 | 851 |
| 1012 // Coprocessor instructions | 852 // Coprocessor instructions |
| 1013 | 853 |
| 1014 void cdp(Coprocessor coproc, int opcode_1, | 854 void cdp(Coprocessor coproc, int opcode_1, |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1422 public: | 1262 public: |
| 1423 explicit EnsureSpace(Assembler* assembler) { | 1263 explicit EnsureSpace(Assembler* assembler) { |
| 1424 assembler->CheckBuffer(); | 1264 assembler->CheckBuffer(); |
| 1425 } | 1265 } |
| 1426 }; | 1266 }; |
| 1427 | 1267 |
| 1428 | 1268 |
| 1429 } } // namespace v8::internal | 1269 } } // namespace v8::internal |
| 1430 | 1270 |
| 1431 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1271 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
| OLD | NEW |