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 ---