From 5de3494e4297c0d480409da3fecee39173f1d4e1 Mon Sep 17 00:00:00 2001 From: buzbee Date: Thu, 1 Mar 2012 14:51:57 -0800 Subject: Another step towards a Mips target Updating the MIPS target to use the now common codegen routines. Still much to do, but the general structure is sufficient to allow work to begin on the other target. Change-Id: I0d288fdfb59c8e76fad73185fdd56b345e87b604 --- src/compiler/codegen/mips/Assemble.cc | 75 +++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 34 deletions(-) (limited to 'src/compiler/codegen/mips/Assemble.cc') diff --git a/src/compiler/codegen/mips/Assemble.cc b/src/compiler/codegen/mips/Assemble.cc index 5b6e6ed771..cb355c0b31 100644 --- a/src/compiler/codegen/mips/Assemble.cc +++ b/src/compiler/codegen/mips/Assemble.cc @@ -75,7 +75,7 @@ namespace art { * * [!] escape. To insert "!", use "!!" */ -/* NOTE: must be kept in sync with enum MipsOpcode from MipsLIR.h */ +/* NOTE: must be kept in sync with enum MipsOpcode from LIR.h */ MipsEncodingMap EncodingMap[kMipsLast] = { ENCODING_MAP(kMips32BitData, 0x00000000, kFmtBitBlt, 31, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, @@ -406,12 +406,10 @@ MipsEncodingMap EncodingMap[kMipsLast] = { AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, intptr_t startAddr) { - UNIMPLEMENTED(FATAL) << "Rework for art code buffer"; -#if 0 - int *bufferAddr = (int *) cUnit->codeBuffer; - MipsLIR *lir; + LIR *lir; + AssemblerStatus res = kSuccess; // Assume success - for (lir = (MipsLIR *) cUnit->firstLIRInsn; lir; lir = NEXT_LIR(lir)) { + for (lir = (LIR *) cUnit->firstLIRInsn; lir; lir = NEXT_LIR(lir)) { if (lir->opcode < 0) { continue; } @@ -422,43 +420,43 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, } if (lir->opcode == kMipsB || lir->opcode == kMipsBal) { - MipsLIR *targetLIR = (MipsLIR *) lir->generic.target; - intptr_t pc = lir->generic.offset + 4; - intptr_t target = targetLIR->generic.offset; + LIR *targetLIR = (LIR *) lir->target; + intptr_t pc = lir->offset + 4; + intptr_t target = targetLIR->offset; int delta = target - pc; if (delta & 0x3) { LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; } if (delta > 131068 || delta < -131069) { - LOG(FATAL) << "Unconditional branch out of range: " << delta; + UNIMPLEMENTED(FATAL) << "B out of range, need long sequence: " << delta; } lir->operands[0] = delta >> 2; } else if (lir->opcode >= kMipsBeqz && lir->opcode <= kMipsBnez) { - MipsLIR *targetLIR = (MipsLIR *) lir->generic.target; - intptr_t pc = lir->generic.offset + 4; - intptr_t target = targetLIR->generic.offset; + LIR *targetLIR = (LIR *) lir->target; + intptr_t pc = lir->offset + 4; + intptr_t target = targetLIR->offset; int delta = target - pc; if (delta & 0x3) { LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; } if (delta > 131068 || delta < -131069) { - LOG(FATAL) << "Conditional branch out of range: " << delta; + UNIMPLEMENTED(FATAL) << "B[eq|ne]z needs long sequence: " << delta; } lir->operands[1] = delta >> 2; } else if (lir->opcode == kMipsBeq || lir->opcode == kMipsBne) { - MipsLIR *targetLIR = (MipsLIR *) lir->generic.target; - intptr_t pc = lir->generic.offset + 4; - intptr_t target = targetLIR->generic.offset; + LIR *targetLIR = (LIR *) lir->target; + intptr_t pc = lir->offset + 4; + intptr_t target = targetLIR->offset; int delta = target - pc; if (delta & 0x3) { LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta; } if (delta > 131068 || delta < -131069) { - LOG(FATAL) << "Conditional branch out of range: " << delta; + UNIMPLEMENTED(FATAL) << "B[eq|ne] needs long sequence: " << delta; } lir->operands[2] = delta >> 2; } else if (lir->opcode == kMipsJal) { - intptr_t curPC = (startAddr + lir->generic.offset + 4) & ~3; + intptr_t curPC = (startAddr + lir->offset + 4) & ~3; intptr_t target = lir->operands[0]; /* ensure PC-region branch can be used */ DCHECK_EQ((curPC & 0xF0000000), (target & 0xF0000000)); @@ -467,16 +465,24 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, } lir->operands[0] = target >> 2; } else if (lir->opcode == kMipsLahi) { /* load address hi (via lui) */ - MipsLIR *targetLIR = (MipsLIR *) lir->generic.target; - intptr_t target = startAddr + targetLIR->generic.offset; + LIR *targetLIR = (LIR *) lir->target; + intptr_t target = startAddr + targetLIR->offset; lir->operands[1] = target >> 16; } else if (lir->opcode == kMipsLalo) { /* load address lo (via ori) */ - MipsLIR *targetLIR = (MipsLIR *) lir->generic.target; - intptr_t target = startAddr + targetLIR->generic.offset; + LIR *targetLIR = (LIR *) lir->target; + intptr_t target = startAddr + targetLIR->offset; lir->operands[2] = lir->operands[2] + target; } - MipsEncodingMap *encoder = &EncodingMap[lir->opcode]; + /* + * If one of the pc-relative instructions expanded we'll have + * to make another pass. Don't bother to fully assemble the + * instruction. + */ + if (res != kSuccess) { + continue; + } + const MipsEncodingMap *encoder = &EncodingMap[lir->opcode]; u4 bits = encoder->skeleton; int i; for (i = 0; i < 4; i++) { @@ -497,7 +503,7 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, break; case kFmtDfp: { DCHECK(DOUBLEREG(operand)); - DCHECK_EQ((operand & 0x1), 0); + DCHECK((operand & 0x1) == 0); value = ((operand & FP_REG_MASK) << encoder->fieldLoc[i].start) & ((1 << (encoder->fieldLoc[i].end + 1)) - 1); bits |= value; @@ -511,14 +517,15 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, break; default: LOG(FATAL) << "Bad encoder format: " - << encoder->fieldLoc[i].kind; + << (int)encoder->fieldLoc[i].kind; } } DCHECK_EQ(encoder->size, 2); - *bufferAddr++ = bits; + // FIXME: need multi-endian handling here + cUnit->codeBuffer.push_back((bits >> 16) & 0xffff); + cUnit->codeBuffer.push_back(bits & 0xffff); } -#endif - return kSuccess; + return res; } /* @@ -528,13 +535,13 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, */ int oatAssignInsnOffsets(CompilationUnit* cUnit) { - MipsLIR* mipsLIR; + LIR* mipsLIR; int offset = 0; - for (mipsLIR = (MipsLIR *) cUnit->firstLIRInsn; - mipsLIR; - mipsLIR = NEXT_LIR(mipsLIR)) { - mipsLIR->generic.offset = offset; + for (mipsLIR = (LIR *) cUnit->firstLIRInsn; + mipsLIR; + mipsLIR = NEXT_LIR(mipsLIR)) { + mipsLIR->offset = offset; if (mipsLIR->opcode >= 0) { if (!mipsLIR->flags.isNop) { mipsLIR->flags.size = EncodingMap[mipsLIR->opcode].size * 2; -- cgit v1.2.3-59-g8ed1b