ARM: Simplify the load/store multiple generation code.

Specifically, get rid of the big switch statement so more cases can be
handled. Enumerating all the possible settings doesn't scale well. Also do
some minor style clean up.
This commit is contained in:
Gabe Black 2009-11-08 15:16:59 -08:00
parent 48525f581c
commit bb903b6514

View file

@ -178,75 +178,46 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
uint32_t regs_to_handle = reglist;
uint32_t start_addr = 0;
uint32_t regs = reglist;
uint32_t addr = 0;
switch (puswl)
{
case 0x00: // stmda
case 0x01: // L ldmda_l
case 0x02: // W stmda_w
case 0x03: // WL ldmda_wl
start_addr = (ones << 2) - 4;
break;
case 0x08: // U stmia_u
case 0x09: // U L ldmia_ul
case 0x0a: // U W stmia
case 0x0b: // U WL ldmia
start_addr = 0;
break;
case 0x10: // P stmdb
case 0x11: // P L ldmdb
case 0x12: // P W stmdb
case 0x13: // P WL ldmdb
start_addr = (ones << 2); // U-bit is already 0 for subtract
break;
case 0x18: // PU stmib
case 0x19: // PU L ldmib
case 0x1a: // PU W stmib
case 0x1b: // PU WL ldmib
start_addr = 4;
break;
default:
panic("Unhandled Load/Store Multiple Instruction, "
"puswl = 0x%x", (unsigned) puswl);
break;
}
if (!up)
addr = (ones << 2) - 4;
if (prepost)
addr += 4;
// Add 0 to Rn and stick it in ureg0.
// This is equivalent to a move.
microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0);
unsigned j = 0;
for (int i = 1; i < ones+1; i++) {
// Get next available bit for transfer
while (! ( regs_to_handle & (1<<j)))
j++;
regs_to_handle &= ~(1<<j);
unsigned reg = 0;
for (int i = 1; i < ones + 1; i++) {
// Find the next register.
while (!bits(regs, reg))
reg++;
replaceBits(regs, reg, 0);
if (loadop)
microOps[i] = new MicroLdrUop(machInst, j,
INTREG_UREG0, start_addr);
microOps[i] = new MicroLdrUop(machInst, reg, INTREG_UREG0, addr);
else
microOps[i] = new MicroStrUop(machInst, j,
INTREG_UREG0, start_addr);
microOps[i] = new MicroStrUop(machInst, reg, INTREG_UREG0, addr);
if (up)
start_addr += 4;
addr += 4;
else
start_addr -= 4;
addr -= 4;
}
StaticInstPtr &lastUop = microOps[numMicroops - 1];
if (writeback) {
if (up) {
microOps[numMicroops-1] =
new MicroAddiUop(machInst, RN, RN, ones * 4);
lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
} else {
microOps[numMicroops-1] =
new MicroSubiUop(machInst, RN, RN, ones * 4);
lastUop = new MicroSubiUop(machInst, RN, RN, ones * 4);
}
}
microOps[numMicroops-1]->setLastMicroop();
lastUop->setLastMicroop();
}
}};
@ -287,14 +258,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
if (writeback)
{
if (up) {
microOps[numMicroops-1] =
microOps[numMicroops - 1] =
new MicroAddiUop(machInst, RN, RN, disp8);
} else {
microOps[numMicroops-1] =
microOps[numMicroops - 1] =
new MicroSubiUop(machInst, RN, RN, disp8);
}
}
microOps[numMicroops-1]->setLastMicroop();
microOps[numMicroops - 1]->setLastMicroop();
}
}};
@ -318,14 +289,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
if (writeback) {
if (up) {
microOps[numMicroops-1] =
microOps[numMicroops - 1] =
new MicroAddiUop(machInst, RN, RN, disp8);
} else {
microOps[numMicroops-1] =
microOps[numMicroops - 1] =
new MicroSubiUop(machInst, RN, RN, disp8);
}
}
microOps[numMicroops-1]->setLastMicroop();
microOps[numMicroops - 1]->setLastMicroop();
}
}};