[arm] Make ADDi into a function, since it's doing a lot of work

This commit is contained in:
Vladimir Vukicevic 2008-09-05 17:14:05 -07:00
parent 2763e5d63e
commit 6ef2cd20aa
2 changed files with 45 additions and 40 deletions

View File

@ -880,6 +880,49 @@ Assembler::B_cond_chk(ConditionCode _c, NIns* _t, bool _chk)
asm_output2("%s %p", _c == AL ? "jmp" : "b(cnd)", (void*)(_t));
}
void
Assembler::asm_add_imm(Register rd, Register rn, int32_t imm)
{
int rot = 16;
uint32_t immval;
bool pos;
if (imm >= 0) {
immval = (uint32_t) imm;
pos = true;
} else {
immval = (uint32_t) (-imm);
pos = false;
}
while (immval && ((immval & 0x3) == 0)) {
immval >>= 2;
rot--;
}
rot &= 0xf;
if (immval < 256) {
underrunProtect(4);
if (pos)
*(--_nIns) = (NIns)( COND_AL | OP_IMM | OP_STAT | (1<<23) | (rn<<16) | (rd<<12) | (rot << 8) | immval );
else
*(--_nIns) = (NIns)( COND_AL | OP_IMM | OP_STAT | (1<<22) | (rn<<16) | (rd<<12) | (rot << 8) | immval );
asm_output3("add %s,%s,%d",gpn(rd),gpn(rn),imm);
} else {
// add scratch to rn, after loading the value into scratch.
// make sure someone isn't trying to use Scratch as an operand
NanoAssert(rn != Scratch);
*(--_nIns) = (NIns)( COND_AL | OP_STAT | (1<<23) | (rn<<16) | (rd<<12) | (Scratch));
asm_output3("add %s,%s,%s",gpn(rd),gpn(rn),gpn(Scratch));
LD32_nochk(Scratch, imm);
}
}
/*
* VFP
*/

View File

@ -200,6 +200,7 @@ verbose_only( extern const char* regNames[]; )
void nativePageReset(); \
void nativePageSetup(); \
void asm_quad_nochk(Register, const int32_t*); \
void asm_add_imm(Register, Register, int32_t); \
int* _nSlot; \
int* _nExitSlot;
@ -308,48 +309,9 @@ typedef enum {
// _l = _l + _r
#define ADD(_l,_r) arm_ADD(_l,_l,_r)
// TODO: we can do better here, since we can rotate the 8-bit immediate left by
// an even number of bits; should count zeros at the end.
// Note that this sometimes converts negative immediate values to a to a sub.
// _d = _r + _imm
#define arm_ADDi(_d,_n,_imm) do { \
if ((_imm) > -256 && (_imm) < 256) { \
underrunProtect(4); \
if ((_imm)>=0) \
*(--_nIns) = (NIns)( COND_AL | OP_IMM | OP_STAT | (1<<23) | ((_n)<<16) | ((_d)<<12) | ((_imm)&0xFF) ); \
else \
*(--_nIns) = (NIns)( COND_AL | OP_IMM | OP_STAT | (1<<22) | ((_n)<<16) | ((_d)<<12) | ((-(_imm))&0xFF) ); \
} else { \
if ((_imm)>=0) { \
if ((_imm)<=1020 && (((_imm)&3)==0) ) { \
underrunProtect(4); \
*(--_nIns) = (NIns)( COND_AL | OP_IMM | OP_STAT | (1<<23) | ((_n)<<16) | ((_d)<<12) | (15<<8)| ((_imm)>>2) ); \
} else { \
underrunProtect(4+LD32_size); \
*(--_nIns) = (NIns)( COND_AL | OP_STAT | (1<<23) | ((_n)<<16) | ((_d)<<12) | (Scratch)); \
LD32_nochk(Scratch, _imm); \
} \
} else { \
underrunProtect(4+LD32_size); \
*(--_nIns) = (NIns)( COND_AL | OP_STAT | (1<<22) | ((_n)<<16) | ((_d)<<12) | (Scratch)); \
LD32_nochk(Scratch, -(_imm)); \
} \
} \
asm_output3("add %s,%s,%d",gpn(_d),gpn(_n),(_imm)); \
} while(0)
/*
* There used to be a :
if ((_imm)>=-510) { \
underrunProtect(8); \
int rem = -(_imm) - 255; \
*(--_nIns) = (NIns)( COND_AL | OP_IMM | (1<<22) | ((_n)<<16) | ((_d)<<12) | ((rem)&0xFF) ); \
*(--_nIns) = (NIns)( COND_AL | OP_IMM | (1<<22) | ((_n)<<16) | ((_d)<<12) | (0xFF) ); \
} else {
* above, but if we do that we can't really update the status registers. So don't do that.
*/
#define arm_ADDi(_d,_n,_imm) asm_add_imm(_d,_n,_imm)
#define ADDi(_r,_imm) arm_ADDi(_r,_r,_imm)
// _l = _l - _r