OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdarg.h> | 5 #include <stdarg.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 if (result == 0) { | 1555 if (result == 0) { |
1556 bf |= 0x20000000; | 1556 bf |= 0x20000000; |
1557 } | 1557 } |
1558 if (setSO) { | 1558 if (setSO) { |
1559 bf |= 0x10000000; | 1559 bf |= 0x10000000; |
1560 } | 1560 } |
1561 condition_reg_ = (condition_reg_ & ~0xF0000000) | bf; | 1561 condition_reg_ = (condition_reg_ & ~0xF0000000) | bf; |
1562 } | 1562 } |
1563 | 1563 |
1564 | 1564 |
1565 void Simulator::ExecuteBranchConditional(Instruction* instr) { | 1565 void Simulator::ExecuteBranchConditional(Instruction* instr, BCType type) { |
1566 int bo = instr->Bits(25, 21) << 21; | 1566 int bo = instr->Bits(25, 21) << 21; |
1567 int offset = (instr->Bits(15, 2) << 18) >> 16; | |
1568 int condition_bit = instr->Bits(20, 16); | 1567 int condition_bit = instr->Bits(20, 16); |
1569 int condition_mask = 0x80000000 >> condition_bit; | 1568 int condition_mask = 0x80000000 >> condition_bit; |
1570 switch (bo) { | 1569 switch (bo) { |
1571 case DCBNZF: // Decrement CTR; branch if CTR != 0 and condition false | 1570 case DCBNZF: // Decrement CTR; branch if CTR != 0 and condition false |
1572 case DCBEZF: // Decrement CTR; branch if CTR == 0 and condition false | 1571 case DCBEZF: // Decrement CTR; branch if CTR == 0 and condition false |
1573 UNIMPLEMENTED(); | 1572 UNIMPLEMENTED(); |
1574 case BF: { // Branch if condition false | 1573 case BF: { // Branch if condition false |
1575 if (!(condition_reg_ & condition_mask)) { | 1574 if (condition_reg_ & condition_mask) return; |
1576 if (instr->Bit(0) == 1) { // LK flag set | |
1577 special_reg_lr_ = get_pc() + 4; | |
1578 } | |
1579 set_pc(get_pc() + offset); | |
1580 } | |
1581 break; | 1575 break; |
1582 } | 1576 } |
1583 case DCBNZT: // Decrement CTR; branch if CTR != 0 and condition true | 1577 case DCBNZT: // Decrement CTR; branch if CTR != 0 and condition true |
1584 case DCBEZT: // Decrement CTR; branch if CTR == 0 and condition true | 1578 case DCBEZT: // Decrement CTR; branch if CTR == 0 and condition true |
1585 UNIMPLEMENTED(); | 1579 UNIMPLEMENTED(); |
1586 case BT: { // Branch if condition true | 1580 case BT: { // Branch if condition true |
1587 if (condition_reg_ & condition_mask) { | 1581 if (!(condition_reg_ & condition_mask)) return; |
1588 if (instr->Bit(0) == 1) { // LK flag set | |
1589 special_reg_lr_ = get_pc() + 4; | |
1590 } | |
1591 set_pc(get_pc() + offset); | |
1592 } | |
1593 break; | 1582 break; |
1594 } | 1583 } |
1595 case DCBNZ: // Decrement CTR; branch if CTR != 0 | 1584 case DCBNZ: // Decrement CTR; branch if CTR != 0 |
1596 case DCBEZ: // Decrement CTR; branch if CTR == 0 | 1585 case DCBEZ: // Decrement CTR; branch if CTR == 0 |
1597 special_reg_ctr_ -= 1; | 1586 special_reg_ctr_ -= 1; |
1598 if ((special_reg_ctr_ == 0) == (bo == DCBEZ)) { | 1587 if ((special_reg_ctr_ == 0) != (bo == DCBEZ)) return; |
1599 if (instr->Bit(0) == 1) { // LK flag set | |
1600 special_reg_lr_ = get_pc() + 4; | |
1601 } | |
1602 set_pc(get_pc() + offset); | |
1603 } | |
1604 break; | 1588 break; |
1605 case BA: { // Branch always | 1589 case BA: { // Branch always |
1606 if (instr->Bit(0) == 1) { // LK flag set | |
1607 special_reg_lr_ = get_pc() + 4; | |
1608 } | |
1609 set_pc(get_pc() + offset); | |
1610 break; | 1590 break; |
1611 } | 1591 } |
1612 default: | 1592 default: |
1613 UNIMPLEMENTED(); // Invalid encoding | 1593 UNIMPLEMENTED(); // Invalid encoding |
1614 } | 1594 } |
| 1595 |
| 1596 intptr_t old_pc = get_pc(); |
| 1597 |
| 1598 switch (type) { |
| 1599 case BC_OFFSET: { |
| 1600 int offset = (instr->Bits(15, 2) << 18) >> 16; |
| 1601 set_pc(old_pc + offset); |
| 1602 break; |
| 1603 } |
| 1604 case BC_LINK_REG: |
| 1605 set_pc(special_reg_lr_); |
| 1606 break; |
| 1607 case BC_CTR_REG: |
| 1608 set_pc(special_reg_ctr_); |
| 1609 break; |
| 1610 } |
| 1611 |
| 1612 if (instr->Bit(0) == 1) { // LK flag set |
| 1613 special_reg_lr_ = old_pc + 4; |
| 1614 } |
1615 } | 1615 } |
1616 | 1616 |
1617 | 1617 |
1618 // Handle execution based on instruction types. | 1618 // Handle execution based on instruction types. |
1619 void Simulator::ExecuteExt1(Instruction* instr) { | 1619 void Simulator::ExecuteExt1(Instruction* instr) { |
1620 switch (instr->Bits(10, 1) << 1) { | 1620 switch (instr->Bits(10, 1) << 1) { |
1621 case MCRF: | 1621 case MCRF: |
1622 UNIMPLEMENTED(); // Not used by V8. | 1622 UNIMPLEMENTED(); // Not used by V8. |
1623 case BCLRX: { | 1623 case BCLRX: |
1624 // need to check BO flag | 1624 ExecuteBranchConditional(instr, BC_LINK_REG); |
1625 intptr_t old_pc = get_pc(); | |
1626 set_pc(special_reg_lr_); | |
1627 if (instr->Bit(0) == 1) { // LK flag set | |
1628 special_reg_lr_ = old_pc + 4; | |
1629 } | |
1630 break; | 1625 break; |
1631 } | 1626 case BCCTRX: |
1632 case BCCTRX: { | 1627 ExecuteBranchConditional(instr, BC_CTR_REG); |
1633 // need to check BO flag | |
1634 intptr_t old_pc = get_pc(); | |
1635 set_pc(special_reg_ctr_); | |
1636 if (instr->Bit(0) == 1) { // LK flag set | |
1637 special_reg_lr_ = old_pc + 4; | |
1638 } | |
1639 break; | 1628 break; |
1640 } | |
1641 case CRNOR: | 1629 case CRNOR: |
1642 case RFI: | 1630 case RFI: |
1643 case CRANDC: | 1631 case CRANDC: |
1644 UNIMPLEMENTED(); | 1632 UNIMPLEMENTED(); |
1645 case ISYNC: { | 1633 case ISYNC: { |
1646 // todo - simulate isync | 1634 // todo - simulate isync |
1647 break; | 1635 break; |
1648 } | 1636 } |
1649 case CRXOR: { | 1637 case CRXOR: { |
1650 int bt = instr->Bits(25, 21); | 1638 int bt = instr->Bits(25, 21); |
(...skipping 1604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3255 if (ra == 0) { // treat r0 as zero | 3243 if (ra == 0) { // treat r0 as zero |
3256 alu_out = im_val; | 3244 alu_out = im_val; |
3257 } else { | 3245 } else { |
3258 intptr_t ra_val = get_register(ra); | 3246 intptr_t ra_val = get_register(ra); |
3259 alu_out = ra_val + im_val; | 3247 alu_out = ra_val + im_val; |
3260 } | 3248 } |
3261 set_register(rt, alu_out); | 3249 set_register(rt, alu_out); |
3262 break; | 3250 break; |
3263 } | 3251 } |
3264 case BCX: { | 3252 case BCX: { |
3265 ExecuteBranchConditional(instr); | 3253 ExecuteBranchConditional(instr, BC_OFFSET); |
3266 break; | 3254 break; |
3267 } | 3255 } |
3268 case BX: { | 3256 case BX: { |
3269 int offset = (instr->Bits(25, 2) << 8) >> 6; | 3257 int offset = (instr->Bits(25, 2) << 8) >> 6; |
3270 if (instr->Bit(0) == 1) { // LK flag set | 3258 if (instr->Bit(0) == 1) { // LK flag set |
3271 special_reg_lr_ = get_pc() + 4; | 3259 special_reg_lr_ = get_pc() + 4; |
3272 } | 3260 } |
3273 set_pc(get_pc() + offset); | 3261 set_pc(get_pc() + offset); |
3274 // todo - AA flag | 3262 // todo - AA flag |
3275 break; | 3263 break; |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3897 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); | 3885 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); |
3898 uintptr_t address = *stack_slot; | 3886 uintptr_t address = *stack_slot; |
3899 set_register(sp, current_sp + sizeof(uintptr_t)); | 3887 set_register(sp, current_sp + sizeof(uintptr_t)); |
3900 return address; | 3888 return address; |
3901 } | 3889 } |
3902 } // namespace internal | 3890 } // namespace internal |
3903 } // namespace v8 | 3891 } // namespace v8 |
3904 | 3892 |
3905 #endif // USE_SIMULATOR | 3893 #endif // USE_SIMULATOR |
3906 #endif // V8_TARGET_ARCH_PPC | 3894 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |