diff options
Diffstat (limited to 'src/compiler/codegen/arm/Assemble.cc')
| -rw-r--r-- | src/compiler/codegen/arm/Assemble.cc | 217 |
1 files changed, 7 insertions, 210 deletions
diff --git a/src/compiler/codegen/arm/Assemble.cc b/src/compiler/codegen/arm/Assemble.cc index 29906310dd..0cd76051d2 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 @@ const ArmEncodingMap EncodingMap[kArmLast] = { */ #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 @@ STATIC AssemblerStatus assembleInstructions(CompilationUnit* cUnit, 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 @@ void assignOffsets(CompilationUnit* cUnit) /* 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 |