summaryrefslogtreecommitdiff
path: root/src/compiler/codegen/arm/Assemble.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/codegen/arm/Assemble.cc')
-rw-r--r--src/compiler/codegen/arm/Assemble.cc217
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