Multi-target support
This CL represents a step towards splitting out the target dependent
and target independent portions of the compiler, and also adds in the
beginning of a MIPS compiler based on the MIPS AOSP Jit submission.
More polish is clearly needed, but the split is here probably pretty
close. The MIPS code will not compile at this point (and there is no
makefile target at present), but it's pretty close.
There should be no changes in functionality of the Arm compiler in this
CL - just moved stuff around.
Change-Id: Ia66b2847e22644a1ec63e66bf5f2fee722f963d4
diff --git a/src/compiler/codegen/arm/Assemble.cc b/src/compiler/codegen/arm/Assemble.cc
index 2990631..0cd7605 100644
--- a/src/compiler/codegen/arm/Assemble.cc
+++ b/src/compiler/codegen/arm/Assemble.cc
@@ -22,8 +22,6 @@
namespace art {
-#define MAX_ASSEMBLER_RETRIES 50
-
/*
* opcode: ArmOpcode enum
* skeleton: pre-designated bit-pattern for this opcode
@@ -977,92 +975,13 @@
*/
#define PADDING_MOV_R5_R5 0x1C2D
-STATIC void pushWord(std::vector<uint16_t>&buf, int data) {
- buf.push_back( data & 0xffff);
- buf.push_back( (data >> 16) & 0xffff);
-}
-
-void alignBuffer(std::vector<uint16_t>&buf, size_t offset) {
- while (buf.size() < (offset/2))
- buf.push_back(0);
-}
-
-/* Write the numbers in the constant to the output stream */
-STATIC void installLiteralPools(CompilationUnit* cUnit)
-{
- alignBuffer(cUnit->codeBuffer, cUnit->dataOffset);
- ArmLIR* dataLIR = (ArmLIR*) cUnit->literalList;
- while (dataLIR) {
- pushWord(cUnit->codeBuffer, dataLIR->operands[0]);
- dataLIR = NEXT_LIR(dataLIR);
- }
-}
-
-/* Write the switch tables to the output stream */
-STATIC void installSwitchTables(CompilationUnit* cUnit)
-{
- GrowableListIterator iterator;
- oatGrowableListIteratorInit(&cUnit->switchTables, &iterator);
- while (true) {
- SwitchTable* tabRec = (SwitchTable *) oatGrowableListIteratorNext(
- &iterator);
- if (tabRec == NULL) break;
- alignBuffer(cUnit->codeBuffer, tabRec->offset);
- int bxOffset = tabRec->bxInst->generic.offset + 4;
- if (cUnit->printMe) {
- LOG(INFO) << "Switch table for offset 0x" << std::hex << bxOffset;
- }
- if (tabRec->table[0] == kSparseSwitchSignature) {
- int* keys = (int*)&(tabRec->table[2]);
- for (int elems = 0; elems < tabRec->table[1]; elems++) {
- int disp = tabRec->targets[elems]->generic.offset - bxOffset;
- if (cUnit->printMe) {
- LOG(INFO) << " Case[" << elems << "] key: 0x" <<
- std::hex << keys[elems] << ", disp: 0x" <<
- std::hex << disp;
- }
- pushWord(cUnit->codeBuffer, keys[elems]);
- pushWord(cUnit->codeBuffer,
- tabRec->targets[elems]->generic.offset - bxOffset);
- }
- } else {
- DCHECK_EQ(tabRec->table[0], kPackedSwitchSignature);
- for (int elems = 0; elems < tabRec->table[1]; elems++) {
- int disp = tabRec->targets[elems]->generic.offset - bxOffset;
- if (cUnit->printMe) {
- LOG(INFO) << " Case[" << elems << "] disp: 0x" <<
- std::hex << disp;
- }
- pushWord(cUnit->codeBuffer,
- tabRec->targets[elems]->generic.offset - bxOffset);
- }
- }
- }
-}
-
-/* Write the fill array dta to the output stream */
-STATIC void installFillArrayData(CompilationUnit* cUnit)
-{
- GrowableListIterator iterator;
- oatGrowableListIteratorInit(&cUnit->fillArrayData, &iterator);
- while (true) {
- FillArrayData *tabRec = (FillArrayData *) oatGrowableListIteratorNext(
- &iterator);
- if (tabRec == NULL) break;
- alignBuffer(cUnit->codeBuffer, tabRec->offset);
- for (int i = 0; i < ((tabRec->size + 1) / 2) ; i++) {
- cUnit->codeBuffer.push_back( tabRec->table[i]);
- }
- }
-}
-
/*
* Assemble the LIR into binary instruction format. Note that we may
* discover that pc-relative displacements may not fit the selected
* instruction.
*/
-STATIC AssemblerStatus assembleInstructions(CompilationUnit* cUnit,
- intptr_t startAddr)
+AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit,
+ intptr_t startAddr)
{
ArmLIR* lir;
AssemblerStatus res = kSuccess; // Assume success
@@ -1461,80 +1380,12 @@
return res;
}
-STATIC int assignLiteralOffsetCommon(LIR* lir, int offset)
-{
- for (;lir != NULL; lir = lir->next) {
- lir->offset = offset;
- offset += 4;
- }
- return offset;
-}
-
-STATIC void createMappingTable(CompilationUnit* cUnit)
-{
- ArmLIR* armLIR;
- int currentDalvikOffset = -1;
-
- for (armLIR = (ArmLIR *) cUnit->firstLIRInsn;
- armLIR;
- armLIR = NEXT_LIR(armLIR)) {
- if ((armLIR->opcode >= 0) && !armLIR->flags.isNop &&
- (currentDalvikOffset != armLIR->generic.dalvikOffset)) {
- // Changed - need to emit a record
- cUnit->mappingTable.push_back(armLIR->generic.offset);
- cUnit->mappingTable.push_back(armLIR->generic.dalvikOffset);
- currentDalvikOffset = armLIR->generic.dalvikOffset;
- }
- }
-}
-
-/* Determine the offset of each literal field */
-STATIC int assignLiteralOffset(CompilationUnit* cUnit, int offset)
-{
- offset = assignLiteralOffsetCommon(cUnit->literalList, offset);
- return offset;
-}
-
-STATIC int assignSwitchTablesOffset(CompilationUnit* cUnit, int offset)
-{
- GrowableListIterator iterator;
- oatGrowableListIteratorInit(&cUnit->switchTables, &iterator);
- while (true) {
- SwitchTable *tabRec = (SwitchTable *) oatGrowableListIteratorNext(
- &iterator);
- if (tabRec == NULL) break;
- tabRec->offset = offset;
- if (tabRec->table[0] == kSparseSwitchSignature) {
- offset += tabRec->table[1] * (sizeof(int) * 2);
- } else {
- DCHECK_EQ(tabRec->table[0], kPackedSwitchSignature);
- offset += tabRec->table[1] * sizeof(int);
- }
- }
- return offset;
-}
-
-STATIC int assignFillArrayDataOffset(CompilationUnit* cUnit, int offset)
-{
- GrowableListIterator iterator;
- oatGrowableListIteratorInit(&cUnit->fillArrayData, &iterator);
- while (true) {
- FillArrayData *tabRec = (FillArrayData *) oatGrowableListIteratorNext(
- &iterator);
- if (tabRec == NULL) break;
- tabRec->offset = offset;
- offset += tabRec->size;
- // word align
- offset = (offset + 3) & ~3;
- }
- return offset;
-}
-
/*
- * Walk the compilation unit and assign offsets to instructions
- * and literals and compute the total size of the compiled unit.
+ * Target-dependent offset assignment.
+ * TODO: normalize usage of flags.size and make this target
+ * independent.
*/
-void assignOffsets(CompilationUnit* cUnit)
+int oatAssignInsnOffsets(CompilationUnit* cUnit)
{
ArmLIR* armLIR;
int offset = 0;
@@ -1559,61 +1410,7 @@
/* Pseudo opcodes don't consume space */
}
- /* Const values have to be word aligned */
- offset = (offset + 3) & ~3;
-
- /* Set up offsets for literals */
- cUnit->dataOffset = offset;
-
- offset = assignLiteralOffset(cUnit, offset);
-
- offset = assignSwitchTablesOffset(cUnit, offset);
-
- offset = assignFillArrayDataOffset(cUnit, offset);
-
- cUnit->totalSize = offset;
-}
-/*
- * Go over each instruction in the list and calculate the offset from the top
- * before sending them off to the assembler. If out-of-range branch distance is
- * seen rearrange the instructions a bit to correct it.
- */
-void oatAssembleLIR(CompilationUnit* cUnit)
-{
- assignOffsets(cUnit);
- /*
- * Assemble here. Note that we generate code with optimistic assumptions
- * and if found now to work, we'll have to redo the sequence and retry.
- */
-
- while (true) {
- AssemblerStatus res = assembleInstructions(cUnit, 0);
- if (res == kSuccess) {
- break;
- } else {
- cUnit->assemblerRetries++;
- if (cUnit->assemblerRetries > MAX_ASSEMBLER_RETRIES) {
- LOG(FATAL) << "Assembler error - too many retries";
- }
- // Redo offsets and try again
- assignOffsets(cUnit);
- cUnit->codeBuffer.clear();
- }
- }
-
- // Install literals
- installLiteralPools(cUnit);
-
- // Install switch tables
- installSwitchTables(cUnit);
-
- // Install fill array data
- installFillArrayData(cUnit);
-
- /*
- * Create the mapping table
- */
- createMappingTable(cUnit);
+ return offset;
}
} // namespace art