macromem.cc (8140:7449084b1612) | macromem.cc (8148:93982cb5044c) |
---|---|
1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 44 unchanged lines hidden (view full) --- 53MacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst, 54 OpClass __opClass, IntRegIndex rn, 55 bool index, bool up, bool user, bool writeback, 56 bool load, uint32_t reglist) : 57 PredMacroOp(mnem, machInst, __opClass) 58{ 59 uint32_t regs = reglist; 60 uint32_t ones = number_of_ones(reglist); | 1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 44 unchanged lines hidden (view full) --- 53MacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst, 54 OpClass __opClass, IntRegIndex rn, 55 bool index, bool up, bool user, bool writeback, 56 bool load, uint32_t reglist) : 57 PredMacroOp(mnem, machInst, __opClass) 58{ 59 uint32_t regs = reglist; 60 uint32_t ones = number_of_ones(reglist); |
61 // Remember that writeback adds a uop 62 numMicroops = ones + (writeback ? 1 : 0) + 1; | 61 // Remember that writeback adds a uop or two and the temp register adds one 62 numMicroops = ones + (writeback ? (load ? 2 : 1) : 0) + 1; 63 64 // It's technically legal to do a lot of nothing 65 if (!ones) 66 numMicroops = 1; 67 |
63 microOps = new StaticInstPtr[numMicroops]; 64 uint32_t addr = 0; 65 66 if (!up) 67 addr = (ones << 2) - 4; 68 69 if (!index) 70 addr += 4; 71 72 StaticInstPtr *uop = microOps; | 68 microOps = new StaticInstPtr[numMicroops]; 69 uint32_t addr = 0; 70 71 if (!up) 72 addr = (ones << 2) - 4; 73 74 if (!index) 75 addr += 4; 76 77 StaticInstPtr *uop = microOps; |
73 StaticInstPtr wbUop; 74 if (writeback) { 75 if (up) { 76 wbUop = new MicroAddiUop(machInst, rn, rn, ones * 4); 77 } else { 78 wbUop = new MicroSubiUop(machInst, rn, rn, ones * 4); 79 } 80 } | |
81 82 // Add 0 to Rn and stick it in ureg0. 83 // This is equivalent to a move. 84 *uop = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0); 85 | 78 79 // Add 0 to Rn and stick it in ureg0. 80 // This is equivalent to a move. 81 *uop = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0); 82 |
86 // Write back at the start for loads. This covers the ldm exception return 87 // case where the base needs to be written in the old mode. Stores may need 88 // the original value of the base, but they don't change mode and can 89 // write back at the end like before. 90 if (load && writeback) { 91 *++uop = wbUop; 92 } 93 | |
94 unsigned reg = 0; | 83 unsigned reg = 0; |
84 unsigned regIdx = 0; |
|
95 bool force_user = user & !bits(reglist, 15); 96 bool exception_ret = user & bits(reglist, 15); 97 98 for (int i = 0; i < ones; i++) { 99 // Find the next register. 100 while (!bits(regs, reg)) 101 reg++; 102 replaceBits(regs, reg, 0); 103 | 85 bool force_user = user & !bits(reglist, 15); 86 bool exception_ret = user & bits(reglist, 15); 87 88 for (int i = 0; i < ones; i++) { 89 // Find the next register. 90 while (!bits(regs, reg)) 91 reg++; 92 replaceBits(regs, reg, 0); 93 |
104 unsigned regIdx = reg; | 94 regIdx = reg; |
105 if (force_user) { 106 regIdx = intRegInMode(MODE_USER, regIdx); 107 } 108 109 if (load) { | 95 if (force_user) { 96 regIdx = intRegInMode(MODE_USER, regIdx); 97 } 98 99 if (load) { |
110 if (reg == INTREG_PC && exception_ret) { 111 // This must be the exception return form of ldm. 112 *++uop = new MicroLdrRetUop(machInst, regIdx, 113 INTREG_UREG0, up, addr); | 100 if (writeback && i == ones - 1) { 101 // If it's a writeback and this is the last register 102 // do the load into a temporary register which we'll move 103 // into the final one later 104 *++uop = new MicroLdrUop(machInst, INTREG_UREG1, INTREG_UREG0, 105 up, addr); |
114 } else { | 106 } else { |
115 *++uop = new MicroLdrUop(machInst, regIdx, 116 INTREG_UREG0, up, addr); | 107 // Otherwise just do it normally 108 if (reg == INTREG_PC && exception_ret) { 109 // This must be the exception return form of ldm. 110 *++uop = new MicroLdrRetUop(machInst, regIdx, 111 INTREG_UREG0, up, addr); 112 } else { 113 *++uop = new MicroLdrUop(machInst, regIdx, 114 INTREG_UREG0, up, addr); 115 } |
117 } 118 } else { 119 *++uop = new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr); 120 } 121 122 if (up) 123 addr += 4; 124 else 125 addr -= 4; 126 } 127 | 116 } 117 } else { 118 *++uop = new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr); 119 } 120 121 if (up) 122 addr += 4; 123 else 124 addr -= 4; 125 } 126 |
128 if (!load && writeback) { 129 *++uop = wbUop; | 127 if (writeback && ones) { 128 // put the register update after we're done all loading 129 if (up) 130 *++uop = new MicroAddiUop(machInst, rn, rn, ones * 4); 131 else 132 *++uop = new MicroSubiUop(machInst, rn, rn, ones * 4); 133 134 // If this was a load move the last temporary value into place 135 // this way we can't take an exception after we update the base 136 // register. 137 if (load && reg == INTREG_PC && exception_ret) { 138 *++uop = new MicroUopRegMovRet(machInst, 0, INTREG_UREG1); 139 warn("creating instruction with exception return at curTick:%d\n", 140 curTick()); 141 } else if (load) { 142 *++uop = new MicroUopRegMov(machInst, regIdx, INTREG_UREG1); 143 if (reg == INTREG_PC) { 144 (*uop)->setFlag(StaticInstBase::IsControl); 145 (*uop)->setFlag(StaticInstBase::IsCondControl); 146 (*uop)->setFlag(StaticInstBase::IsIndirectControl); 147 // This is created as a RAS POP 148 if (rn == INTREG_SP) 149 (*uop)->setFlag(StaticInstBase::IsReturn); 150 151 } 152 } |
130 } 131 132 (*uop)->setLastMicroop(); 133 134 for (StaticInstPtr *curUop = microOps; 135 !(*curUop)->isLastMicroop(); curUop++) { 136 MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get()); 137 assert(uopPtr); --- 808 unchanged lines hidden --- | 153 } 154 155 (*uop)->setLastMicroop(); 156 157 for (StaticInstPtr *curUop = microOps; 158 !(*curUop)->isLastMicroop(); curUop++) { 159 MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get()); 160 assert(uopPtr); --- 808 unchanged lines hidden --- |