diff --git a/.gitignore b/.gitignore index 8e0e258..a9099fd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,8 @@ tags *.pyc +<<<<<<< HEAD +======= +*.swp +>>>>>>> develop build/ tests/ diff --git a/amoco/arch/arm/cpu_armv7.py b/amoco/arch/arm/cpu_armv7.py index 4301c69..8854c76 100644 --- a/amoco/arch/arm/cpu_armv7.py +++ b/amoco/arch/arm/cpu_armv7.py @@ -14,6 +14,10 @@ from amoco.arch.arm.v7 import spec_armv7 from amoco.arch.arm.v7 import spec_thumb +from amoco.arch.arm.v7.formats import ARM_V7_full +instruction.set_formatter(ARM_V7_full) + + mode = (lambda : internals['isetstate']) endian = (lambda : 1 if internals['endianstate']==0 else -1) diff --git a/amoco/arch/arm/v7/asm.py b/amoco/arch/arm/v7/asm.py index f3e6a34..c32b58f 100644 --- a/amoco/arch/arm/v7/asm.py +++ b/amoco/arch/arm/v7/asm.py @@ -7,6 +7,7 @@ #utilities: #---------- +from .utils import * from amoco.cas.utils import * from amoco.logger import Log @@ -15,10 +16,11 @@ #------------------------------------------------------------------------------ # low level functions : + def _switch_isetstate(): _s = internals['isetstate'] internals['isetstate'] = 0 if _s==1 else 1 - logger.info('switch to %s instructions'%({'ARM','Thumb'}[internals['isetstate']])) + logger.info('switch to %s instructions'%({0:'ARM',1:'Thumb'}[internals['isetstate']])) def __check_state(i,fmap): address = fmap(pc) @@ -32,385 +34,436 @@ def __check_state(i,fmap): else: logger.warning('impossible to check isetstate (ARM/Thumb) until pc is cst') +def __pre(i,fmap): + fmap[pc] = fmap(pc+i.length) + cond = fmap(CONDITION[i.cond][1]) + dest,op1 = i.operands[0:2] + if op1 is pc: op1=op1+i.length + if len(i.operands)==3: + op2 = i.operands[2] + if op2 is pc: op2=op2+i.length + return cond,dest,op1,op2 + if len(i.operands)>3: + ops = tuple(i.operands[3:]) + return (cond,dest,op1,op2)+ops + return cond,dest,op1 + +def __setflags(fmap,cond,cout,result,overflow=None): + fmap[C] = tst(cond,cout,fmap(C)) + fmap[Z] = tst(cond,(result==0),fmap(Z)) + fmap[N] = tst(cond,(result<0),fmap(N)) + if overflow is not None: + fmap[V] = tst(cond,overflow,fmap(V)) + # i_xxx is the translation of UAL (ARM/Thumb) instruction xxx. #------------------------------------------------------------------------------ # Branch instructions (A4.3, pA4-7) def i_B(i,fmap): + fmap[pc] = fmap(pc+i.length) cond = CONDITION[i.cond][1] - fmap[pc] = fmap(tst(cond,pc+i.imm32,pc+i.length)) + pcoffset = i.length + if internals['isetstate'] and pcoffset==4: pcoffset=0 + fmap[pc] = fmap(tst(cond,pc+i.imm32+pcoffset,pc)) __check_state(i,fmap) def i_CBNZ(i,fmap): + fmap[pc] = fmap(pc+i.length) op1,op2 = i.operands - fmap[pc] = tst(fmap(i.n)!=0,pc+i.imm32,pc+i.length) + fmap[pc] = fmap(tst(i.n!=0,pc+i.imm32+i.length,pc)) __check_state(i,fmap) def i_CBZ(i,fmap): + fmap[pc] = fmap(pc+i.length) op1,op2 = i.operands - fmap[pc] = tst(fmap(i.n)==0,pc+i.imm32,pc+i.length) + fmap[pc] = fmap(tst(i.n==0,pc+i.imm32+i.length,pc)) __check_state(i,fmap) def i_BL(i,fmap): - fmap[lr] = fmap(pc) fmap[pc] = fmap(pc+i.length) + fmap[lr] = fmap(pc) offset = i.operands[0] + cond = CONDITION[i.cond][1] + pcoffset = i.length + if internals['isetstate']==1 and pcoffset==4: pcoffset=0 + fmap[pc] = fmap(tst(cond,pc+offset+pcoffset,pc)) __check_state(i,fmap) def i_BLX(i,fmap): - fmap[lr] = fmap(pc) fmap[pc] = fmap(pc+i.length) - offset = i.operands[0] + fmap[lr] = fmap(pc) + src = i.operands[0] + cond = CONDITION[i.cond][1] + fmap[pc] = fmap(tst(cond,src,pc)) __check_state(i,fmap) def i_BX(i,fmap): fmap[pc] = fmap(pc+i.length) - offset = i.operands[0] + src = i.operands[0] + cond = CONDITION[i.cond][1] + fmap[pc] = fmap(tst(cond,src,pc)) _switch_isetstate() def i_BXJ(i,fmap): - fmap[lr] = fmap(pc) fmap[pc] = fmap(pc+i.length) - offset = i.operands[0] + fmap[lr] = fmap(pc) + src = i.operands[0] + cond = CONDITION[i.cond][1] + fmap[pc] = fmap(tst(cond,src,pc)) internals['isetstate'] = 2 logger.error('switch to Jazelle instructions (unsupported)') -#def i_TBB(i,fmap): pass -#def i_TBH(i,fmap): pass - # Data processing instructions (A4.4) # standard (4.4.1): def i_ADC(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands + cond,dest,op1,op2 = __pre(i,fmap) result,cout,overflow = AddWithCarry(fmap(op1),fmap(op2),fmap(C)) - fmap[dest] = tst(cond,result,dest) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[V] = tst(cond,overflow,V) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result,overflow) def i_ADD(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands + cond,dest,op1,op2 = __pre(i,fmap) result,cout,overflow = AddWithCarry(fmap(op1),fmap(op2)) - fmap[dest] = tst(cond,result,dest) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[V] = tst(cond,overflow,V) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result,overflow) def i_ADR(i,fmap): + fmap[pc] = fmap(pc+i.length) if i.add: - result = fmap(pc%4)+i.imm32 + result = fmap(pc&0xFFFFFFFC)+i.imm32+i.length else: - result = fmap(pc%4)-i.imm32 - cond = CONDITION[i.cond][1] - fmap[i.d] = tst(cond,result,i.d) + result = fmap(pc&0xFFFFFFFC)-i.imm32+i.length + cond = fmap(CONDITION[i.cond][1]) + fmap[i.d] = tst(cond,result,fmap(i.d)) def i_AND(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands + cond,dest,op1,op2 = __pre(i,fmap) result = fmap(op1 & op2) - fmap[dest] = tst(cond,result,dest) + cout = fmap(op2.bit(31)) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result) def i_BIC(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands + cond,dest,op1,op2 = __pre(i,fmap) result = fmap(op1 & (~op2)) - fmap[dest] = tst(cond,result,dest) + cout = fmap(op2.bit(31)) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result) def i_CMN(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands + cond,dest,op1,op2 = __pre(i,fmap) result,cout,overflow = AddWithCarry(fmap(op1),fmap(op2)) - fmap[C] = tst(cond,cout,C) - fmap[V] = tst(cond,overflow,V) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result,overflow) def i_CMP(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands + cond,dest,op1,op2 = __pre(i,fmap) result,cout,overflow = SubWithBorrow(fmap(op1),fmap(op2)) - fmap[C] = tst(cond,cout,C) - fmap[V] = tst(cond,overflow,V) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result,overflow) def i_EOR(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands + cond,dest,op1,op2 = __pre(i,fmap) result = fmap(op1 ^ op2) - fmap[dest] = tst(cond,result,dest) + cout = fmap(op2.bit(31)) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result) def i_MOV(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1 = i.operands + cond,dest,op1 = __pre(i,fmap) result = fmap(op1) - fmap[dest] = tst(cond,result,dest) + cout = fmap(op1.bit(31)) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result) def i_MOVW(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1 = i.operands + cond,dest,op1 = __pre(i,fmap) result = fmap(op1) - fmap[dest] = tst(cond,result,dest) + cout = fmap(op1.bit(31)) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result) def i_MVN(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1 = i.operands + cond,dest,op1 = __pre(i,fmap) result = fmap(~op1) - fmap[dest] = tst(cond,result,dest) + cout = fmap(op1.bit(31)) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result) def i_ORN(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands + cond,dest,op1,op2 = __pre(i,fmap) result = fmap(op1 | ~op2) - fmap[dest] = tst(cond,result,dest) + cout = fmap(op2.bit(31)) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result) def i_ORR(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands + cond,dest,op1,op2 = __pre(i,fmap) result = fmap(op1 | op2) - fmap[dest] = tst(cond,result,dest) + cout = fmap(op2.bit(31)) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result) def i_RSB(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands + cond,dest,op1,op2 = __pre(i,fmap) result,cout,overflow = AddWithCarry(fmap(~op1),fmap(op2),bit1) - fmap[dest] = tst(cond,result,dest) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[V] = tst(cond,overflow,V) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result,overflow) def i_RSC(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands - result,cout,overflow = AddWithCarry(fmap(~op1),fmap(op2),fmap(C)) - fmap[dest] = tst(cond,result,dest) - if dest is pc: - __check_state(i,fmap) - elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[V] = tst(cond,overflow,V) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + cond,dest,op1,op2 = __pre(i,fmap) + result,cout,overflow = AddWithCarry(fmap(~op1),fmap(op2),fmap(C)) + fmap[dest] = tst(cond,result,fmap(dest)) + if dest is pc: + __check_state(i,fmap) + elif i.setflags: + __setflags(fmap,cond,cout,result,overflow) def i_SBC(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands - result,cout,overflow = AddWithCarry(fmap(op1),fmap(~op2),fmap(C)) - fmap[dest] = tst(cond,result,dest) - if dest is pc: - __check_state(i,fmap) - elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[V] = tst(cond,overflow,V) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + cond,dest,op1,op2 = __pre(i,fmap) + result,cout,overflow = AddWithCarry(fmap(op1),fmap(~op2),fmap(C)) + fmap[dest] = tst(cond,result,fmap(dest)) + if dest is pc: + __check_state(i,fmap) + elif i.setflags: + __setflags(fmap,cond,cout,result,overflow) def i_SUB(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands - result,cout,overflow = AddWithCarry(fmap(op1),fmap(~op2),bit1) - fmap[dest] = tst(cond,result,dest) - if dest is pc: - __check_state(i,fmap) - elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[V] = tst(cond,overflow,V) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + cond,dest,op1,op2 = __pre(i,fmap) + result,cout,overflow = AddWithCarry(fmap(op1),fmap(~op2),bit1) + fmap[dest] = tst(cond,result,fmap(dest)) + if dest is pc: + __check_state(i,fmap) + elif i.setflags: + __setflags(fmap,cond,cout,result,overflow) def i_TEQ(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands + cond,dest,op1,op2 = __pre(i,fmap) result = fmap(op1 ^ op2) - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + cout = fmap(op2.bit(31)) + __setflags(fmap,cond,cout,result) def i_TST(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands + cond,dest,op1,op2 = __pre(i,fmap) result = fmap(op1 & op2) - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + cout = fmap(op2.bit(31)) + __setflags(fmap,cond,cout,result) # shifts (4.4.2) def i_ASR(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands - result,cout = ASR_C(fmap(op1),fmap(op2)) - fmap[dest] = tst(cond,result,dest) + cond,dest,op1,op2 = __pre(i,fmap) + shift = fmap(op2) + if shift._is_cst: + result,cout = ASR_C(fmap(op1),shift.value) + else: + result,cout = fmap(ap1>>ap2), top(1) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result) def i_LSL(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands - result,cout = LSL_C(fmap(op1),fmap(op2)) - fmap[dest] = tst(cond,result,dest) + cond,dest,op1,op2 = __pre(i,fmap) + shift = fmap(op2) + if shift._is_cst: + result,cout = LSL_C(fmap(op1),shift.value) + else: + result,cout = fmap(ap1<>ap2), top(1) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result) def i_ROR(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2 = i.operands - result,cout = ROR_C(fmap(op1),fmap(op2)) - fmap[dest] = tst(cond,result,dest) + cond,dest,op1,op2 = __pre(i,fmap) + shift = fmap(op2) + if shift._is_cst: + result,cout = ROR_C(fmap(op1),shift.value) + else: + result,cout = ror(ap1,ap2), top(1) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result) def i_RRX(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1 = i.operands + cond,dest,op1 = __pre(i,fmap) result,cout = RRX_C(fmap(op1),fmap(C)) - fmap[dest] = tst(cond,result,dest) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[C] = tst(cond,cout,C) - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + __setflags(fmap,cond,cout,result) # multiply (4.4.3) # general: def i_MLA(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2,addend = i.operands - result = (op1*op2)+addend - fmap[dest] = tst(cond,result,dest) + cond,dest,op1,op2,addend = __pre(i,fmap) + result = fmap((op1*op2)+addend) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) elif i.setflags: - fmap[Z] = tst(cond,(result==0),Z) - fmap[N] = tst(cond,(result<0),N) + fmap[Z] = tst(cond,(result==0),fmap(Z)) + fmap[N] = tst(cond,(result<0),fmap(N)) -# MLS def i_MLS(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,op1,op2,addend = i.operands - result = addend-(op1*op2) - fmap[dest] = tst(cond,result,dest) + cond,dest,op1,op2,addend = __pre(i,fmap) + result = fmap(addend-(op1*op2)) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: __check_state(i,fmap) -# MUL +def i_MUL(i,fmap): + cond,dest,op1,op2 = __pre(i,fmap) + result = fmap(op1*op2) + fmap[dest] = tst(cond,result,fmap(dest)) + # signed: # SMLABB, SMLABT, SMLATB, SMLATT -# SMLAD -# SMLAL -# SMLALBB, SMLALBT, SMLALTB, SMLALTT +def i_SMLABB(i,fmap): + cond,dest,Rn,Rm,Ra = __pre(i,fmap) + op1 = Rn[0:16] + op2 = Rm[0:16] + result = fmap((op1**op2) + Ra) + fmap[dest] = tst(cond,result,fmap(dest)) + overflow = top(1) + fmap[V] = tst(cond,overflow,fmap(V)) + +def i_SMLABT(i,fmap): + cond,dest,Rn,Rm,Ra = __pre(i,fmap) + op1 = Rn[0:16] + op2 = Rm[16:32] + result = fmap((op1**op2) + Ra) + fmap[dest] = tst(cond,result,fmap(dest)) + overflow = top(1) + fmap[V] = tst(cond,overflow,fmap(V)) + +def i_SMLATT(i,fmap): + cond,dest,Rn,Rm,Ra = __pre(i,fmap) + op1 = Rn[16:32] + op2 = Rm[16:32] + result = fmap((op1**op2) + Ra) + fmap[dest] = tst(cond,result,fmap(dest)) + overflow = top(1) + fmap[V] = tst(cond,overflow,fmap(V)) + +def i_SMLATB(i,fmap): + cond,dest,Rn,Rm,Ra = __pre(i,fmap) + op1 = Rn[16:32] + op2 = Rm[0:16] + result = fmap((op1**op2) + Ra) + fmap[dest] = tst(cond,result,fmap(dest)) + overflow = top(1) + fmap[V] = tst(cond,overflow,fmap(V)) + +def i_SMLAD(i,fmap): + cond,dest,Rn,Rm,Ra = __pre(i,fmap) + p1 = Rn[0:16] ** Rm[0:16] + p2 = Rn[16:32] ** Rm[16:32] + result = fmap(p1 + p2 + Ra) + fmap[dest] = tst(cond,result,fmap(dest)) + overflow = top(1) + fmap[V] = tst(cond,overflow,fmap(V)) + +def i_SMLADX(i,fmap): + cond,dest,Rn,Rm,Ra = __pre(i,fmap) + p1 = Rn[0:16] ** Rm[16:32] + p2 = Rn[16:32] ** Rm[0:16] + result = fmap(p1 + p2 + Ra) + fmap[dest] = tst(cond,result,fmap(dest)) + overflow = top(1) + fmap[V] = tst(cond,overflow,fmap(V)) + +def i_SMLAL(i,fmap): + cond,RdLo,RdHi,Rn,Rm = __pre(i,fmap) + result = fmap(Rn**Rm + composer([RdLo,RdHi])) + fmap[RdLo] = tst(cond,result[0:32],fmap(RdLo)) + fmap[RdHi] = tst(cond,result[32:64],fmap(RdHi)) + if i.setflags: + fmap[Z] = tst(cond,(result==0),fmap(Z)) + fmap[N] = tst(cond,result.bit(63),fmap(N)) + +def i_SMLALBB(i,fmap): + cond,RdLo,RdHi,Rn,Rm = __pre(i,fmap) + op1 = Rn[0:16] + op2 = Rm[0:16] + result = fmap((op1**op2).signextend(64) + composer([RdLo,RdHi])) + fmap[RdLo] = tst(cond,result[0:32],fmap(RdLo)) + fmap[RdHi] = tst(cond,result[32:64],fmap(RdHi)) + +def i_SMLALBT(i,fmap): + cond,RdLo,RdHi,Rn,Rm = __pre(i,fmap) + op1 = Rn[0:16] + op2 = Rm[16:32] + result = fmap((op1**op2).signextend(64) + composer([RdLo,RdHi])) + fmap[RdLo] = tst(cond,result[0:32],fmap(RdLo)) + fmap[RdHi] = tst(cond,result[32:64],fmap(RdHi)) + +def i_SMLALTT(i,fmap): + cond,RdLo,RdHi,Rn,Rm = __pre(i,fmap) + op1 = Rn[16:32] + op2 = Rm[16:32] + result = fmap((op1**op2).signextend(64) + composer([RdLo,RdHi])) + fmap[RdLo] = tst(cond,result[0:32],fmap(RdLo)) + fmap[RdHi] = tst(cond,result[32:64],fmap(RdHi)) + +def i_SMLALTB(i,fmap): + cond,RdLo,RdHi,Rn,Rm = __pre(i,fmap) + op1 = Rn[16:32] + op2 = Rm[0:16] + result = fmap((op1**op2).signextend(64) + composer([RdLo,RdHi])) + fmap[RdLo] = tst(cond,result[0:32],fmap(RdLo)) + fmap[RdHi] = tst(cond,result[32:64],fmap(RdHi)) + # SMLALD # SMLAWB, SMLAWT # SMLSD @@ -447,36 +500,30 @@ def i_MLS(i,fmap): # miscellaneous (4.4.6) def i_BFC(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,lsb,size = i.operands + cond,dest,lsb,size = __pre(i,fmap) src = fmap(dest) result = composer([src[0:lsb],cst(0,size),src[lsb+size:src.size]]) - fmap[dest] = tst(cond,result,dest) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: raise InstructionError(i) def i_BFI(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,src,lsb,size = i.operands + cond,dest,src,lsb,size = __pre(i,fmap) src = fmap(src) result = composer([dest[0:lsb],src[lsb,lsb+size],dest[lsb+size:dest.size]]) - fmap[dest] = tst(cond,result,dest) + fmap[dest] = tst(cond,result,fmap(dest)) if dest is pc: raise InstructionError(i) def i_CLZ(i,fmap): - fmap[pc] = fmap(pc+i.length) - cond = CONDITION[i.cond][1] - dest,src = i.operands + cond,dest,src = __pre(i,fmap) result = fmap(src) if result._is_cst: result = [(result.value>>i)&1 for i in range(result.size)] result = cst(result.find(1),dest.size) else: result = top(dest.size) - fmap[dest] = tst(cond,result,dest) + fmap[dest] = tst(cond,result,fmap(dest)) # MOVT # RBIT @@ -508,42 +555,346 @@ def i_CLZ(i,fmap): # MSR # load/store (A4.6) -# LDR, LDRH, LDRSH, LDRB, LDRSB, LDRD -# STR, STRH, STRB, STRD -# LDRT, LDRHT, LDRSHT, LDRBT, LDRSBT -# STRT, STRHT, STRBT -# LDREX, LDREXH, LDREXB, LDREXD -# STREX, STREXH, STREXB, STREXD - -# load/store mulitple (A4.7) +def i_LDR(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.index else src + result = fmap(mem(adr,32)) + if i.wback: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + fmap[dest] = tst(cond,result,fmap(dest)) + +def i_LDREX(i,fmap): + cond,dest,src,imm = __pre(i,fmap) + off_addr = (src+imm) + adr = off_addr + result = fmap(mem(adr,32)) + fmap[dest] = tst(cond,result,fmap(dest)) + # exclusive monitor not supported + +def i_LDRB(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.index else src + result = fmap(mem(adr,8)).zeroextend(32) + fmap[dest] = tst(cond,result,fmap(dest)) + if i.wback: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + +def i_LDREXB(i,fmap): + cond,dest,src,imm = __pre(i,fmap) + off_addr = (src+imm) + adr = off_addr + result = fmap(mem(adr,8)).zeroextend(32) + fmap[dest] = tst(cond,result,fmap(dest)) + # exclusive monitor not supported + +def i_LDRH(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.index else src + result = fmap(mem(adr,16)).zeroextend(32) + fmap[dest] = tst(cond,result,fmap(dest)) + if i.wback: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + +def i_LDREXH(i,fmap): + cond,dest,src,imm = __pre(i,fmap) + off_addr = (src+imm) + adr = off_addr + result = fmap(mem(adr,16)).zeroextend(32) + fmap[dest] = tst(cond,result,fmap(dest)) + # exclusive monitor not supported + +def i_LDRSB(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.index else src + result = fmap(mem(adr,8)).signextend(32) + fmap[dest] = tst(cond,result,fmap(dest)) + if i.wback: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + +def i_LDRSH(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.index else src + result = fmap(mem(adr,16)).signextend(32) + fmap[dest] = tst(cond,result,fmap(dest)) + if i.wback: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + +def i_LDRD(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.index else src + res1 = fmap(mem(adr,32)) + res2 = fmap(mem(adr+4,32)) + fmap[dst1] = tst(cond,res1,fmap(dst1)) + fmap[dst2] = tst(cond,res2,fmap(dst2)) + if i.wback: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + +def i_LDRT(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.postindex else src + result = fmap(mem(adr,32)) + if i.postindex: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + fmap[dest] = tst(cond,result,fmap(dest)) + +def i_LDRBT(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.postindex else src + result = fmap(mem(adr,8)).zeroextend(32) + if i.postindex: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + fmap[dest] = tst(cond,result,fmap(dest)) + +def i_LDRHT(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.postindex else src + result = fmap(mem(adr,16)).zeroextend(32) + if i.postindex: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + fmap[dest] = tst(cond,result,fmap(dest)) + +def i_LDRSBT(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.postindex else src + result = fmap(mem(adr,8)).signextend(32) + if i.postindex: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + fmap[dest] = tst(cond,result,fmap(dest)) + +def i_LDRSHT(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.postindex else src + result = fmap(mem(adr,16)).signextend(32) + if i.postindex: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + fmap[dest] = tst(cond,result,fmap(dest)) + +def i_STR(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.index else src + result = fmap(dest) + if i.wback: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + fmap[mem(adr,32)] = tst(cond,result,fmap(mem(adr,32))) + +def i_STREX(i,fmap): + cond,dest,src,imm = __pre(i,fmap) + off_addr = (src+imm) + adr = off_addr + result = fmap(dest) + fmap[mem(adr,32)] = tst(cond,result,fmap(mem(adr,32))) + # exclusive monitor not supported + +def i_STRB(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.index else src + result = fmap(dest[0:8]) + fmap[mem(adr,8)] = tst(cond,result,mem(adr,8)) + if i.wback: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + +def i_STREXB(i,fmap): + cond,dest,src,imm = __pre(i,fmap) + off_addr = (src+imm) + adr = off_addr + result = fmap(dest[0:8]) + fmap[mem(adr,8)] = tst(cond,result,fmap(mem(adr,8))) + # exclusive monitor not supported + +def i_STRH(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.index else src + result = fmap(dest[0:16]) + fmap[mem(adr,16)] = tst(cond,result,fmap(mem(adr,16))) + if i.wback: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + +def i_STREXH(i,fmap): + cond,dest,src,imm = __pre(i,fmap) + off_addr = (src+imm) + adr = off_addr + result = fmap(dest[0:16]) + fmap[mem(adr,16)] = tst(cond,result,fmap(mem(adr,16))) + # exclusive monitor not supported + +def i_STRD(i,fmap): + fmap[pc] = fmap(pc+i.length) + cond = fmap(CONDITION[i.cond][1]) + dst1,dst2,src,sht = i.operands + if src is pc: src = src+i.length + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.index else src + adr1 = mem(adr,32) + adr2 = mem(adr+4,32) + res1 = fmap(dst1) + res2 = fmap(dst2) + fmap[adr1] = tst(cond,res1,fmap(adr1)) + fmap[adr2] = tst(cond,res2,fmap(adr2)) + if i.wback: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + +def i_STRT(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.postindex else src + adr1 = mem(adr,32) + result = fmap(dest) + if i.postindex: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + fmap[adr1] = tst(cond,result,fmap(adr1)) + +def i_STRBT(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.postindex else src + adr1 = mem(adr,8) + result = fmap(dest[0:8]) + if i.postindex: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + fmap[adr1] = tst(cond,result,fmap(adr1)) + +def i_STRHT(i,fmap): + cond,dest,src,sht = __pre(i,fmap) + off_addr = (src+sht) if i.add else (src-sht) + adr = off_addr if i.postindex else src + adr1 = mem(adr,16) + result = fmap(dest[0:16]) + if i.postindex: + fmap[src] = tst(cond,fmap(off_addr),fmap(src)) + fmap[adr1] = tst(cond,result,fmap(adr1)) + +# load/store multiple (A4.7) # LDM, LDMIA, LDMFD # LDMDA, LDMFA # LDMDB, LDMEA # LDMIB, LDMED -# POP -# PUSH + +def i_POP(i,fmap): + fmap[pc] = fmap(pc+i.length) + cond = CONDITION[i.cond][1] + regs = i.operands[0] + adr = sp + for _r in regs: + fmap[_r] = fmap(tst(cond,mem(adr,32),_r)) + adr = adr+4 + fmap[sp] = fmap(tst(cond,sp+(4*len(regs)),sp)) + +def i_PUSH(i,fmap): + fmap[pc] = fmap(pc+i.length) + cond = CONDITION[i.cond][1] + regs = i.operands[0] + adr = sp-(4*len(regs)) + for _r in regs: + if _r is pc: _r = _r+i.length + fmap[mem(adr,32)] = fmap(tst(cond,_r,mem(adr,32))) + adr = adr+4 + fmap[sp] = fmap(tst(cond,sp-(4*len(regs)),sp)) + # STM, STMIA, STMEA # STMDA, STMED # STMDB, STMFD # STMIB, STMFA # miscellaneous (A4.8) -# CLREX -# DBG -# DMB -# DSB -# ISB -# IT -# NOP -# PLD, PLDW -# PLI -# SETEND -# SEV -# SVC -# SWP, SWPB -# WFE -# WFI -# YIELD + +def i_CLREX(i,fmap): + fmap[pc] = fmap(pc+i.length) + # exclusive monitor not supported + +def i_DBG(i,fmap): + fmap[pc] = fmap(pc+i.length) + # debug hint + +def i_DMB(i,fmap): + fmap[pc] = fmap(pc+i.length) + +def i_DSB(i,fmap): + fmap[pc] = fmap(pc+i.length) + +def i_ISB(i,fmap): + fmap[pc] = fmap(pc+i.length) + +def i_IT(i,fmap): + assert internals['isetstate']==1 + fmap[pc] = fmap(pc+i.length) + internals['itstate'] = 1 + +def i_NOP(i,fmap): + fmap[pc] = fmap(pc+i.length) + +def i_WFE(i,fmap): + fmap[pc] = fmap(pc+i.length) + +def i_WFI(i,fmap): + fmap[pc] = fmap(pc+i.length) + +def i_YIELD(i,fmap): + fmap[pc] = fmap(pc+i.length) + +# pre-load data hint +def i_PLD(i,fmap): + fmap[pc] = fmap(pc+i.length) + +# pre-load data wide hint +def i_PLDW(i,fmap): + fmap[pc] = fmap(pc+i.length) + +# pre-load instruction hint +def i_PLI(i,fmap): + fmap[pc] = fmap(pc+i.length) + +# change endianess +def i_SETEND(i,fmap): + fmap[pc] = fmap(pc+i.length) + internals['endianstate'] = 1 if i.set_bigend else 0 + +# event hint +def i_SEV(i,fmap): + fmap[pc] = fmap(pc+i.length) + +# supervisor call +def i_SVC(i,fmap): + fmap[pc] = fmap(pc+i.length) + logger.info('call to supervisor is unsupported') + +def i_SWP(i,fmap): + fmap[pc] = fmap(pc+i.length) + Rt,Rt2,Rn = i.operands + data = fmap(mem(Rn,32)) + fmap[mem(Rn,32)] = fmap(Rt2) + fmap[Rt] = data + +def i_SWPB(i,fmap): + fmap[pc] = fmap(pc+i.length) + Rt,Rt2,Rn = i.operands + data = fmap(mem(Rn,8)) + fmap[mem(Rn,8)] = fmap(Rt2)[0:8] + fmap[Rt] = data.zeroextend(32) + +def i_ENTERX(i,fmap): + fmap[pc] = fmap(pc+i.length) + internals['isetstate'] = 3 + +def i_LEAVEX(i,fmap): + fmap[pc] = fmap(pc+i.length) + internals['isetstate'] = 1 + +def i_SMC(i,fmap): + raise InstructionError(i) # coprocessor (A4.9) # MCR, MCR2 diff --git a/amoco/arch/arm/v7/env.py b/amoco/arch/arm/v7/env.py index b97c81e..f1ed206 100644 --- a/amoco/arch/arm/v7/env.py +++ b/amoco/arch/arm/v7/env.py @@ -81,7 +81,7 @@ # internal states not exposed to symbolic interpreter: #----------------------------------------------------- internals = { # states MUST be in a mutable object ! - 'isetstate' : 0, #0: ARM, 1: Thumb + 'isetstate' : 0, #0: ARM, 1: Thumb, 2: Jazelle, 3: ThumbEE 'itstate' : 0, # thumb internal parameter (see IT instruction) 'endianstate': 0, #0: LE, 1: BE } diff --git a/amoco/arch/arm/v7/formats.py b/amoco/arch/arm/v7/formats.py new file mode 100644 index 0000000..14cfaba --- /dev/null +++ b/amoco/arch/arm/v7/formats.py @@ -0,0 +1,95 @@ +from .env import * +from .utils import * +from amoco.arch.core import Formatter + +def mnemo(i): + m = i.mnemonic + if hasattr(i,'setflags') and i.setflags: + m += 'S' + if hasattr(i,'cond') and i.cond!=CONDITION_AL: + m += '.%s'%CONDITION[i.cond][0] + return '%s'%(m.lower()).ljust(12) + +def regs(i,limit=None): + ops = i.operands + if limit: ops = ops[:limit] + return ['{0}'.format(r) for r in ops] + +def reglist(i,pos=-1): + l = i.operands[pos] + return "{%s}"%(', '.join(['{0}'.format(r) for r in l])) + +def deref(i,pos=-2): + assert len(i.operands)>2 + base,offset = i.operands[pos], i.operands[pos+1] + sign = '+' if i.add else '-' + if offset._is_cst: + ostr = '#%c%d'%(sign,offset.value) + else: + ostr = sign+str(offset) + if hasattr(i,'wback'): + wb = '!' if i.wback else '' + if i.index: + loc = '[%s, %s]%s'%(base, ostr, wb) + else: + loc = '[%s], %s'%(base, ostr) + else: + loc = '[%s], %s'%(base,ostr) + return [loc] + +def label(i,pos=0): + _pc = i.address + if _pc is None: _pc=pc + pcoffset = 4 if internals['isetstate']==0 else 2 + _pc = _pc + 2*pcoffset + offset = i.operands[pos] + return '*'+str(_pc+offset) + +def setend(i): + endian_specifier = 'BE' if i.set_bigend else 'LE' + return mnemo(i)+endian_specifier + +def plx(i): + m = mnemo(i) + base,offset = i.operands[-2], i.operands[-1] + sign = '+' if i.add else '-' + if offset._is_cst: + ostr = '#%c%d'%(sign,offset.value) + else: + ostr = sign+str(offset) + loc = '[%s, %s]'%(base, ostr) + return m+loc + +def specreg(i): + spec_reg = "%s_"%apsr + if i.write_nzcvq: spec_reg += 'nzcvq' + if i.write_g: spec_reg += 'g' + return '%s, %s'%(i.operands[0],spec_reg) + +format_allregs = [lambda i: ', '.join(regs(i))] +format_default = [mnemo]+format_allregs +format_sreg = format_default +format_label = [mnemo, label] +format_adr = [mnemo, lambda i: '{0}, '.format(i.operands[0]), lambda i: label(i,1)] +format_bits = format_default +format_reglist = [mnemo, (lambda i: ', '.join(regs(i,-1))), reglist] +format_deref = [mnemo, lambda i: ', '.join(regs(i,-2)+deref(i,-2))] +format_plx = [plx] +format_msr = [mnemo, specreg] +format_setend = [setend] + +ARM_V7_full_formats = { + 'A_default' : format_default, + 'A_sreg' : format_sreg, + 'A_label' : format_label, + 'A_adr' : format_adr, + 'A_bits' : format_bits, + 'A_reglist' : format_reglist, + 'A_deref' : format_deref, + 'instr_PLx' : format_plx, + 'instr_MSR' : format_msr, + 'instr_SETEND' : format_setend, +} + +ARM_V7_full = Formatter(ARM_V7_full_formats) + diff --git a/amoco/arch/arm/v7/spec_armv7.py b/amoco/arch/arm/v7/spec_armv7.py index 4e095eb..81663e2 100644 --- a/amoco/arch/arm/v7/spec_armv7.py +++ b/amoco/arch/arm/v7/spec_armv7.py @@ -3,7 +3,6 @@ # published under GPLv2 license # spec_xxx files are providers for instruction objects. -# These objects are wrapped and created by disasm.py. from amoco.arch.arm.v7 import env @@ -26,13 +25,14 @@ @ispec("32[ .cond(4) 00 1 0111 S Rn(4) Rd(4) imm12(12) ]", mnemonic="RSC") @ispec("32[ .cond(4) 00 1 1100 S Rn(4) Rd(4) imm12(12) ]", mnemonic="ORR") @ispec("32[ .cond(4) 00 1 1110 S Rn(4) Rd(4) imm12(12) ]", mnemonic="BIC") -def A1_immediate(obj,S,Rn,Rd,imm12): +def A_default(obj,S,Rn,Rd,imm12): obj.setflags = (S==1) obj.n = env.regs[Rn] obj.d = env.regs[Rd] obj.imm32 = ARMExpandImm(imm12) obj.operands = [obj.d,obj.n,obj.imm32] obj.type = type_data_processing + if obj.d is env.pc: obj.type = type_control_flow @ispec("32[ .cond(4) 00 0 0000 S Rn(4) Rd(4) imm5(5) stype(2) 0 Rm(4) ]", mnemonic="AND") @ispec("32[ .cond(4) 00 0 0001 S Rn(4) Rd(4) imm5(5) stype(2) 0 Rm(4) ]", mnemonic="EOR") @@ -44,13 +44,14 @@ def A1_immediate(obj,S,Rn,Rd,imm12): @ispec("32[ .cond(4) 00 0 0111 S Rn(4) Rd(4) imm5(5) stype(2) 0 Rm(4) ]", mnemonic="RSC") @ispec("32[ .cond(4) 00 0 1100 S Rn(4) Rd(4) imm5(5) stype(2) 0 Rm(4) ]", mnemonic="ORR") @ispec("32[ .cond(4) 00 0 1110 S Rn(4) Rd(4) imm5(5) stype(2) 0 Rm(4) ]", mnemonic="BIC") -def A1_register(obj,S,Rn,Rd,imm5,stype,Rm): +def A_sreg(obj,S,Rn,Rd,imm5,stype,Rm): obj.setflags = (S==1) obj.n = env.regs[Rn] obj.d = env.regs[Rd] - obj.m = DecodeShift(stype,env.regs[Rm],imm5) + obj.m = DecodeShift(stype,env.regs[Rm],env.cst(imm5,5)) obj.operands = [obj.d,obj.n,obj.m] obj.type = type_data_processing + if obj.d is env.pc: obj.type = type_control_flow @ispec("32[ .cond(4) 00 0 0000 S Rn(4) Rd(4) Rs(4) 0 stype(2) 1 Rm(4) ]", mnemonic="AND") @ispec("32[ .cond(4) 00 0 0001 S Rn(4) Rd(4) Rs(4) 0 stype(2) 1 Rm(4) ]", mnemonic="EOR") @@ -62,9 +63,10 @@ def A1_register(obj,S,Rn,Rd,imm5,stype,Rm): @ispec("32[ .cond(4) 00 0 0111 S Rn(4) Rd(4) Rs(4) 0 stype(2) 1 Rm(4) ]", mnemonic="RSC") @ispec("32[ .cond(4) 00 0 1100 S Rn(4) Rd(4) Rs(4) 0 stype(2) 1 Rm(4) ]", mnemonic="ORR") @ispec("32[ .cond(4) 00 0 1110 S Rn(4) Rd(4) Rs(4) 0 stype(2) 1 Rm(4) ]", mnemonic="BIC") -def A1_shifted_register(obj,S,Rn,Rd,Rs,stype,Rm): +def A_sreg(obj,S,Rn,Rd,Rs,stype,Rm): obj.setflags = (S==1) obj.n = env.regs[Rn] + if 15 in (Rd,Rs,Rm,Rn): raise InstructionError(obj) obj.d = env.regs[Rd] obj.m = DecodeShift(stype,env.regs[Rm],env.regs[Rs]) obj.operands = [obj.d,obj.n,obj.m] @@ -72,47 +74,68 @@ def A1_shifted_register(obj,S,Rn,Rd,Rs,stype,Rm): @ispec("32[ .cond(4) 00 1 0100 S 1111 Rd(4) imm12(12) ]", mnemonic="ADR", add=True ) @ispec("32[ .cond(4) 00 1 0010 S 1111 Rd(4) imm12(12) ]", mnemonic="ADR", add=False) +def A_adr(obj,S,Rd,imm12): + obj.setflags = (S==1) + obj.d = env.regs[Rd] + obj.imm32 = ARMExpandImm(imm12) + obj.operands = [obj.d,obj.imm32] + obj.type = type_data_processing + if obj.d is env.pc: obj.type = type_control_flow + @ispec("32[ .cond(4) 00 1 1101 S 0000 Rd(4) imm12(12) ]", mnemonic="MOV") @ispec("32[ .cond(4) 00 1 1111 S 0000 Rd(4) imm12(12) ]", mnemonic="MVN") -def instr_ADR(obj,S,Rd,imm12): +def A_default(obj,S,Rd,imm12): obj.setflags = (S==1) obj.d = env.regs[Rd] obj.imm32 = ARMExpandImm(imm12) obj.operands = [obj.d,obj.imm32] obj.type = type_data_processing + if obj.d is env.pc: obj.type = type_control_flow @ispec("32[ .cond(4) 00 0 1101 S 0000 Rd(4) imm5(5) 100 Rm(4) ]", mnemonic="ASR") @ispec("32[ .cond(4) 00 0 1101 S 0000 Rd(4) imm5(5) 000 Rm(4) ]", mnemonic="LSL") @ispec("32[ .cond(4) 00 0 1101 S 0000 Rd(4) imm5(5) 010 Rm(4) ]", mnemonic="LSR") @ispec("32[ .cond(4) 00 0 1101 S 0000 Rd(4) imm5(5) 110 Rm(4) ]", mnemonic="ROR") -def asr_imm(obj,S,Rd,imm5,Rm): +def A_default(obj,S,Rd,imm5,Rm): obj.setflags = (S==1) obj.d = env.regs[Rd] obj.m = env.regs[Rm] - obj.operands = [obj.d,obj.m,imm5] obj.type = type_data_processing + if imm5==0: + shift_n = 32 if obj.mnemonic in ('LSR','ASR') else imm5 + if obj.mnemonic=='ROR': + obj.mnemonic='RRX' + obj.operands = [obj.d,obj.m] + return + else: + shift_n = imm5 + obj.operands = [obj.d,obj.m,env.cst(shift_n,5)] + if obj.d is env.pc: obj.type = type_control_flow @ispec("32[ .cond(4) 00 0 1101 S 0000 Rd(4) Rm(4) 0101 Rn(4) ]", mnemonic="ASR") @ispec("32[ .cond(4) 00 0 1101 S 0000 Rd(4) Rm(4) 0001 Rn(4) ]", mnemonic="LSL") @ispec("32[ .cond(4) 00 0 1101 S 0000 Rd(4) Rm(4) 0011 Rn(4) ]", mnemonic="LSR") @ispec("32[ .cond(4) 00 0 0000 S Rd(4) 0000 Rm(4) 1001 Rn(4) ]", mnemonic="MUL") @ispec("32[ .cond(4) 00 0 1101 S 0000 Rd(4) Rm(4) 0111 Rn(4) ]", mnemonic="ROR") -def asr_reg(obj,S,Rd,Rm,Rn): +def A_default(obj,S,Rd,Rm,Rn): obj.setflags = (S==1) + if 15 in (Rd,Rm,Rn): raise InstructionError(obj) obj.d = env.regs[Rd] obj.m = env.regs[Rm] obj.n = env.regs[Rn] + if obj.mnemonic != 'MUL': obj.m = obj.m[0:8] obj.operands = [obj.d,obj.n,obj.m] obj.type = type_data_processing @ispec("32[ .cond(4) 1010 imm24(24) ]", mnemonic="B") -def instr_B(obj,imm24): +def A_label(obj,imm24): obj.imm32 = env.cst(imm24<<2,26).signextend(32) obj.operands = [obj.imm32] obj.type = type_control_flow @ispec("32[ .cond(4) 0111110 msb(5) Rd(4) lsb(5) 001 Rn(4) ]") -def instr_BFC_BFI(obj,msb,Rd,lsb,Rn): +def A_bits(obj,msb,Rd,lsb,Rn): + if Rd==15: raise InstructionError(obj) obj.d = env.regs[Rd] obj.msbit = msb obj.lsbit = lsb @@ -126,19 +149,19 @@ def instr_BFC_BFI(obj,msb,Rd,lsb,Rn): obj.type = type_data_processing @ispec("32[ .cond(4) 00010010 imm12(12) 0111 imm4(4) ]", mnemonic="BKPT") -def instr_BKPT(obj,imm12,imm4): +def A_default(obj,imm12,imm4): obj.imm32 = env.cst((imm12<<4)+imm4,32) obj.operands = [obj.imm32] obj.type = type_data_processing @ispec("32[ .cond(4) 101 1 imm24(24) ]", mnemonic="BL") -def instr_BL_imm(obj,imm24): +def A_label(obj,imm24): obj.imm32 = env.cst(imm24<<2,26).signextend(32) obj.operands = [obj.imm32] obj.type = type_control_flow @ispec("32[ 1111 101 H imm24(24) ]", menmonic="BLX") -def instr_BLX_imm(obj,H,imm24): +def A_label(obj,H,imm24): H = 2*H obj.imm32 = env.cst((imm24<<2)+H,26).signextend(32) obj.operands = [obj.imm32] @@ -147,13 +170,15 @@ def instr_BLX_imm(obj,H,imm24): @ispec("32[ .cond(4) 00010010 1111 1111 1111 0011 Rm(4) ]", mnemonic="BLX") @ispec("32[ .cond(4) 00010010 1111 1111 1111 0001 Rm(4) ]", mnemonic="BX") @ispec("32[ .cond(4) 00010010 1111 1111 1111 0010 Rm(4) ]", mnemonic="BXJ") -def instr_BX_BLX_reg(obj,Rm): - obj.n = env.regs[Rm] - obj.operands = [obj.n] +def A_default(obj,Rm): + if obj.mnemonic!="BX" and Rm==15: raise InstructionError(obj) + obj.m = env.regs[Rm] + obj.operands = [obj.m] obj.type = type_control_flow @ispec("32[ 1111 01010111 1111 1111 0000 0001 1111 ]", mnemonic="CLREX") -def instr_clrex(obj): +def A_default(obj): + obj.operands = [] obj.type = type_data_processing @ispec("32[ .cond(4) 0011 0010 0000 1111 0000 00000000 ]", mnemonic="NOP") @@ -161,11 +186,12 @@ def instr_clrex(obj): @ispec("32[ .cond(4) 0011 0010 0000 1111 0000 00000010 ]", mnemonic="WFE") @ispec("32[ .cond(4) 0011 0010 0000 1111 0000 00000011 ]", mnemonic="WFI") @ispec("32[ .cond(4) 0011 0010 0000 1111 0000 00000100 ]", mnemonic="SEV") -def instr_noop(obj): +def A_default(obj): obj.type = type_cpu_state @ispec("32[ .cond(4) 00010110 1111 Rd(4) 1111 0001 Rm(4) ]", mnemonic="CLZ") -def instr_CLZ(obj,Rd,Rm): +def A_default(obj,Rd,Rm): + if 15 in (Rd,Rm): raise InstructionError(obj) obj.d = env.regs[Rd] obj.m = env.regs[Rm] obj.operands = [obj.d, obj.n] @@ -175,18 +201,19 @@ def instr_CLZ(obj,Rd,Rm): @ispec("32[ .cond(4) 00 1 1010 1 Rn(4) 0000 imm12(12) ]", mnemonic="CMP") @ispec("32[ .cond(4) 00 1 1001 1 Rn(4) 0000 imm12(12) ]", mnemonic="TEQ") @ispec("32[ .cond(4) 00 1 1000 1 Rn(4) 0000 imm12(12) ]", mnemonic="TST") -def instr_CMx_i(obj,Rn,imm12): +def A_default(obj,Rn,imm12): obj.n = env.regs[Rn] obj.imm32 = ARMExpandImm(imm12) + obj.operands = [obj.n, obj.imm32] obj.type = type_data_processing @ispec("32[ .cond(4) 00 0 1011 1 Rn(4) 0000 imm5(5) stype(2) 0 Rm(4) ]", mnemonic="CMN") @ispec("32[ .cond(4) 00 0 1010 1 Rn(4) 0000 imm5(5) stype(2) 0 Rm(4) ]", mnemonic="CMP") @ispec("32[ .cond(4) 00 0 1001 1 Rn(4) 0000 imm5(5) stype(2) 0 Rm(4) ]", mnemonic="TEQ") @ispec("32[ .cond(4) 00 0 1000 1 Rn(4) 0000 imm5(5) stype(2) 0 Rm(4) ]", mnemonic="TST") -def instr_CMx_r(obj,Rn,imm5,stype,Rm): +def A_sreg(obj,Rn,imm5,stype,Rm): obj.n = env.regs[Rn] - obj.m = DecodeShift(stype,env.regs[Rm],imm5) + obj.m = DecodeShift(stype,env.regs[Rm],env.cst(imm5,5)) obj.operands = [obj.n,obj.m] obj.type = type_data_processing @@ -194,7 +221,8 @@ def instr_CMx_r(obj,Rn,imm5,stype,Rm): @ispec("32[ .cond(4) 00 0 1010 1 Rn(4) 0000 Rs(4) 0 stype(2) 1 Rm(4) ]", mnemonic="CMP") @ispec("32[ .cond(4) 00 0 1001 1 Rn(4) 0000 Rs(4) 0 stype(2) 1 Rm(4) ]", mnemonic="TEQ") @ispec("32[ .cond(4) 00 0 1000 1 Rn(4) 0000 Rs(4) 0 stype(2) 1 Rm(4) ]", mnemonic="TST") -def instr_CMx_sr(obj,Rn,Rs,stype,Rm): +def A_sreg(obj,Rn,Rs,stype,Rm): + if 15 in (Rd,Rm,Rs): raise InstructionError(obj) obj.n = env.regs[Rn] obj.m = DecodeShift(stype,env.regs[Rm],env.regs[Rs]) obj.operands = [obj.n,obj.m] @@ -204,7 +232,8 @@ def instr_CMx_sr(obj,Rn,Rs,stype,Rm): @ispec("32[ 1111 01010111 1111 1111 0000 0101 .option(4) ]", mnemonic="DMB") @ispec("32[ 1111 01010111 1111 1111 0000 0100 .option(4) ]", mnemonic="DSB") @ispec("32[ 1111 01010111 1111 1111 0000 0110 .option(4) ]", mnemonic="ISB") -def instr_debugandsynch(obj): +def A_default(obj): + obj.operands = [] obj.type = type_cpu_state @ispec("32[ .cond(4) 100010 W 1 Rn(4) ~register_list(16) ]", mnemonic="LDM") @@ -215,73 +244,97 @@ def instr_debugandsynch(obj): @ispec("32[ .cond(4) 100000 W 0 Rn(4) ~register_list(16) ]", mnemonic="STMDA") @ispec("32[ .cond(4) 100100 W 0 Rn(4) ~register_list(16) ]", mnemonic="STMDB") @ispec("32[ .cond(4) 100110 W 0 Rn(4) ~register_list(16) ]", mnemonic="STMIB") -def instr_LDMx(obj,W,Rn,register_list): +def A_reglist(obj,W,Rn,register_list): obj.n = env.regs[Rn] obj.registers = [env.regs[i] for i,r in enumerate(register_list) if r==1] obj.wback = (W==1) + if Rn==15 or len(obj.registers)<1: raise InstructionError(obj) + if obj.wback and (obj.n in obj.registers): raise InstructionError(obj) obj.operands = [obj.n,obj.registers] obj.type = type_data_processing + if env.pc in obj.registers: obj.type = type_control_flow @ispec("32[ .cond(4) 010 P U 0 W 1 Rn(4) Rt(4) imm12(12) ]", mnemonic="LDR") @ispec("32[ .cond(4) 010 P U 1 W 1 Rn(4) Rt(4) imm12(12) ]", mnemonic="LDRB") @ispec("32[ .cond(4) 010 P U 0 W 0 Rn(4) Rt(4) imm12(12) ]", mnemonic="STR") @ispec("32[ .cond(4) 010 P U 1 W 0 Rn(4) Rt(4) imm12(12) ]", mnemonic="STRB") -def instr_LDR_i(obj,P,U,W,Rn,Rt,imm12): +def A_deref(obj,P,U,W,Rn,Rt,imm12): obj.n = env.regs[Rn] obj.t = env.regs[Rt] obj.imm32 = env.cst(imm12,32) + if Rn==15: + if not (P==1 and W==0): + raise InstructionError(obj) if P==0 and W==1: obj.mnemonic += 'T' obj.postindex = True obj.register_form = False + if (15 in (Rt,Rn)) or (Rn==Rt): raise InstructionError(obj) else: obj.index = (P==1) obj.wback = (P==0)|(W==1) + if obj.wback and Rn==Rt: raise InstructionError(obj) obj.add = (U==1) obj.operands = [obj.t,obj.n,obj.imm32] obj.type = type_data_processing + if obj.t is env.pc : obj.type = type_control_flow @ispec("32[ .cond(4) 011 P U 0 W 1 Rn(4) Rt(4) imm5(5) stype(2) 0 Rm(4) ]", mnemonic="LDR") @ispec("32[ .cond(4) 011 P U 1 W 1 Rn(4) Rt(4) imm5(5) stype(2) 0 Rm(4) ]", mnemonic="LDRB") @ispec("32[ .cond(4) 011 P U 0 W 0 Rn(4) Rt(4) imm5(5) stype(2) 0 Rm(4) ]", mnemonic="STR") @ispec("32[ .cond(4) 011 P U 1 W 0 Rn(4) Rt(4) imm5(5) stype(2) 0 Rm(4) ]", mnemonic="STRB") -def instr_LDR_r(obj,P,U,W,Rn,Rt,imm5,stype,Rm): +def A_deref(obj,P,U,W,Rn,Rt,imm5,stype,Rm): obj.n = env.regs[Rn] obj.t = env.regs[Rt] obj.m = DecodeShift(stype,env.regs[Rm],imm5) + if Rn==15: + if not (P==1 and W==0): + raise InstructionError(obj) if P==0 and W==1: obj.mnemonic += 'T' obj.postindex = True obj.register_form = True + if (15 in (Rt,Rn,Rm)) or (Rn==Rt): raise InstructionError(obj) else: obj.index = (P==1) obj.wback = (P==0)|(W==1) + if Rm==15: raise InstructionError(obj) + if obj.wback and (Rn==15 or Rn==Rt): raise InstructionError(obj) obj.add = (U==1) obj.operands = [obj.t,obj.n,obj.m] obj.type = type_data_processing + if obj.t is env.pc : obj.type = type_control_flow @ispec("32[ .cond(4) 000 P U 1 W 0 Rn(4) Rt(4) imm4H(4) 1101 imm4L(4) ]", mnemonic="LDRD") @ispec("32[ .cond(4) 000 P U 1 W 0 Rn(4) Rt(4) imm4H(4) 1111 imm4L(4) ]", mnemonic="STRD") -def instr_LDRD_i(obj,P,U,W,Rn,Rt,imm4H,imm4L): +def A_deref(obj,P,U,W,Rn,Rt,imm4H,imm4L): obj.n = env.regs[Rn] obj.t = env.regs[Rt] obj.t2 = env.regs[Rt+1] + if Rt==14 or Rt%2==1: raise InstructionError(obj) obj.imm32 = env.cst(imm4H<<4+imm4L,32) obj.index = (P==1) obj.wback = (P==0)|(W==1) obj.add = (U==1) + if obj.wback and (Rn==15 or Rn==Rt or Rn==Rt+1): raise InstructionError(obj) obj.operands = [obj.t,obj.t2,obj.n,obj.imm32] obj.type = type_data_processing @ispec("32[ .cond(4) 000 P U 0 W 0 Rn(4) Rt(4) 0000 1101 Rm(4) ]", mnemonic="LDRD") @ispec("32[ .cond(4) 000 P U 0 W 0 Rn(4) Rt(4) 0000 1111 Rm(4) ]", mnemonic="STRD") -def instr_LDRD_r(obj,P,U,W,Rn,Rt,Rm): +def A_deref(obj,P,U,W,Rn,Rt,Rm): obj.n = env.regs[Rn] obj.t = env.regs[Rt] obj.m = env.regs[Rm] obj.t2 = env.regs[Rt+1] + if P==0 and W==1: raise InstructionError(obj) + if Rt==14 or Rm==15: raise InstructionError(obj) + if Rn==15: + if not (P==1 and W==0): + raise InstructionError(obj) obj.index = (P==1) obj.wback = (P==0)|(W==1) + if obj.wback and (Rn==15 or Rn==Rt or Rn==Rt+1): raise InstructionError(obj) obj.add = (U==1) obj.operands = [obj.t,obj.t2,obj.n,obj.m] obj.type = type_data_processing @@ -290,9 +343,10 @@ def instr_LDRD_r(obj,P,U,W,Rn,Rt,Rm): @ispec("32[ .cond(4) 0001110 1 Rn(4) Rt(4) 1111 1001 1111 ]", mnemonic="LDREXB") @ispec("32[ .cond(4) 0001101 1 Rn(4) Rt(4) 1111 1001 1111 ]", mnemonic="LDREXD") @ispec("32[ .cond(4) 0001111 1 Rn(4) Rt(4) 1111 1001 1111 ]", mnemonic="LDREXH") -def instr_LDREX(obj,Rn,Rt): +def A_default(obj,Rn,Rt): obj.n = env.regs[Rn] obj.t = env.regs[Rt] + if Rn==15 or Rt==15: raise InstructionError(obj) obj.operands = [obj.t,obj.n] if obj.mnemonic=='LDREXD': obj.t2 = env.regs[Rt+1] @@ -303,7 +357,9 @@ def instr_LDREX(obj,Rn,Rt): @ispec("32[ .cond(4) 0001110 0 Rn(4) Rd(4) 1111 1001 Rt(4) ]", mnemonic="STREXB") @ispec("32[ .cond(4) 0001101 0 Rn(4) Rd(4) 1111 1001 Rt(4) ]", mnemonic="STREXD") @ispec("32[ .cond(4) 0001111 0 Rn(4) Rd(4) 1111 1001 Rt(4) ]", mnemonic="STREXH") -def instr_STREX(obj,Rn,Rd,Rt): +def A_default(obj,Rn,Rd,Rt): + if 15 in (Rt,Rn,Rd) : raise InstructionError(obj) + if Rn==Rd or Rd==Rt : raise InstructionError(obj) obj.d = env.regs[Rd] obj.n = env.regs[Rn] obj.t = env.regs[Rt] @@ -317,7 +373,7 @@ def instr_STREX(obj,Rn,Rd,Rt): @ispec("32[ .cond(4) 000 P U 1 W 1 Rn(4) Rt(4) imm4H(4) 1101 imm4L(4) ]", mnemonic="LDRSB") @ispec("32[ .cond(4) 000 P U 1 W 1 Rn(4) Rt(4) imm4H(4) 1111 imm4L(4) ]", mnemonic="LDRSH") @ispec("32[ .cond(4) 000 P U 1 W 0 Rn(4) Rt(4) imm4H(4) 1011 imm4L(4) ]", mnemonic="STRH") -def instr_LDRSx_i(obj,P,U,W,Rn,Rt,imm4H,imm4L): +def A_deref(obj,P,U,W,Rn,Rt,imm4H,imm4L): obj.n = env.regs[Rn] obj.t = env.regs[Rt] obj.imm32 = env.cst(imm4H<<4+imm4L,32) @@ -325,9 +381,11 @@ def instr_LDRSx_i(obj,P,U,W,Rn,Rt,imm4H,imm4L): obj.mnemonic += "T" obj.postindex = True obj.register_form = False + if (15 in (Rt,Rn)) or (Rn==Rt): raise InstructionError(obj) else: obj.index = (P==1) obj.wback = (P==0)|(W==1) + if Rt==15 or (obj.wback and Rn==Rt): raise InstructionError(obj) obj.add = (U==1) obj.operands = [obj.t,obj.n,obj.imm32] obj.type = type_data_processing @@ -336,7 +394,7 @@ def instr_LDRSx_i(obj,P,U,W,Rn,Rt,imm4H,imm4L): @ispec("32[ .cond(4) 000 P U 0 W 1 Rn(4) Rt(4) 0000 1101 Rm(4) ]", mnemonic="LDRSB") @ispec("32[ .cond(4) 000 P U 0 W 1 Rn(4) Rt(4) 0000 1111 Rm(4) ]", mnemonic="LDRSH") @ispec("32[ .cond(4) 000 P U 0 W 0 Rn(4) Rt(4) 0000 1011 Rm(4) ]", mnemonic="STRH") -def instr_LDRSx_r(obj,P,U,W,Rn,Rt,Rm): +def A_deref(obj,P,U,W,Rn,Rt,Rm): obj.n = env.regs[Rn] obj.t = env.regs[Rt] obj.m = env.regs[Rm] @@ -344,25 +402,29 @@ def instr_LDRSx_r(obj,P,U,W,Rn,Rt,Rm): obj.mnemonic += "T" obj.postindex = True obj.register_form = True + if (15 in (Rt,Rn,Rm)) or (Rn==Rt): raise InstructionError(obj) else: obj.index = (P==1) obj.wback = (P==0)|(W==1) + if Rt==15 or Rm==15: raise InstructionError(obj) + if obj.wback and (Rn==15 or Rn==Rt): raise InstructionError(obj) obj.add = (U==1) obj.operands = [obj.t,obj.n,obj.m] obj.type = type_data_processing @ispec("32[ .cond(4) 0000001 S Rd(4) Ra(4) Rm(4) 1001 Rn(4) ]", mnemonic="MLA") -def instr_MLA(obj,S,Rd,Ra,Rm,Rn): +def A_default(obj,S,Rd,Ra,Rm,Rn): obj.setflags = (S==1) obj.d = env.regs[Rd] obj.n = env.regs[Rn] obj.m = env.regs[Rm] obj.a = env.regs[Ra] + if 15 in (Rd,Rn,Rm,Ra): raise InstructionError(obj) obj.operands = [obj.d,obj.n,obj.m,obj.a] obj.type = type_data_processing @ispec("32[ .cond(4) 0011 0000 imm4(4) Rd(4) imm12(12) ]", mnemonic="MOVW") -def instr_MOVW(obj,imm4,Rd,imm12): +def A_default(obj,imm4,Rd,imm12): obj.setflags = False obj.d = env.regs[Rd] obj.imm32 = ARMExpandImm(imm4<<12+imm12) @@ -371,28 +433,31 @@ def instr_MOVW(obj,imm4,Rd,imm12): @ispec("32[ .cond(4) 00 0 1101 S 0000 Rd(4) 00000 000 Rm(4) ]", mnemonic="MOV") @ispec("32[ .cond(4) 00 0 1101 S 0000 Rd(4) 00000 110 Rm(4) ]", mnemonic="RRX") -def instr_MOV_reg(obj,S,Rd,Rm): +def A_default(obj,S,Rd,Rm): obj.setflags = (S==1) obj.d = env.regs[Rd] obj.m = env.regs[Rm] obj.operands = [obj.d,obj.m] obj.type = type_data_processing + if obj.d is env.pc: obj.type = type_control_flow @ispec("32[ .cond(4) 0011 0100 imm4(4) Rd(4) imm12(12) ]", mnemonic="MOVT") -def instr_MOVT(obj,imm4,Rd,imm12): +def A_default(obj,imm4,Rd,imm12): obj.d = env.regs[Rd] + if Rd==15: raise InstructionError(obj) obj.imm16 = env.cst(imm4<<12+imm12,16) obj.operands = [obj.d,obj.imm16] obj.type = type_data_processing @ispec("32[ .cond(4) 00010000 1111 Rd(4) 0000 0000 0000 ]", mnemonic="MRS") -def instr_MRS(obj,Rd): +def A_default(obj,Rd): obj.d = env.regs[Rd] - obj.operands = [obj.d] + if Rd==15: raise InstructionError(obj) + obj.operands = [obj.d, env.apsr] obj.type = type_data_processing @ispec("32[ .cond(4) 00110010 ~mask(2) 00 1111 imm12(12) ]", mnemonic="MSR") -def instr_MSR_imm(obj,mask,imm12): +def instr_MSR(obj,mask,imm12): obj.imm32 = ARMExpandImm(imm12) obj.write_nzcvq = (mask[1]==1) obj.write_g = (mask[0]==1) @@ -400,7 +465,7 @@ def instr_MSR_imm(obj,mask,imm12): obj.type = type_data_processing @ispec("32[ .cond(4) 00010 0 10 ~mask(2) 00 1111 0000 0000 Rn(4) ]", mnemonic="MSR") -def instr_MSR_reg(obj,mask,Rn): +def instr_MSR(obj,mask,Rn): obj.n = env.regs[Rn] obj.write_nzcvq = (mask[1]==1) obj.write_g = (mask[0]==1) @@ -408,50 +473,56 @@ def instr_MSR_reg(obj,mask,Rn): obj.type = type_data_processing @ispec("32[ .cond(4) 00 0 1111 S 0000 Rd(4) imm5(5) stype(2) 0 Rm(4) ]", mnemonic="MVN") -def instr_MVN_reg(obj,S,Rd,imm5,stype,Rm): +def A_sreg(obj,S,Rd,imm5,stype,Rm): obj.setflags = (S==1) obj.d = env.regs[Rd] obj.m = DecodeShift(stype,env.regs[Rm],imm5) obj.operands = [obj.d,obj.m] obj.type = type_data_processing + if obj.d is env.pc: obj.type = type_control_flow @ispec("32[ .cond(4) 00 0 1111 S 0000 Rd(4) Rs(4) 0 stype(2) 1 Rm(4) ]", mnemonic="MVN") -def instr_MVN_sreg(obj,S,Rd,Rs,stype,Rm): +def A_sreg(obj,S,Rd,Rs,stype,Rm): obj.setflags = (S==1) obj.d = env.regs[Rd] obj.m = DecodeShift(stype,env.regs[Rm],env.regs[Rs]) + if 15 in (Rd,Rm,Rs): raise InstructionError(obj) obj.operands = [obj.d,obj.m] obj.type = type_data_processing @ispec("32[ .cond(4) 01101000 Rn(4) Rd(4) imm5(5) tb 01 Rm(4) ]", mnemonic="PKH") -def instr_PKHx(obj,Rn,Rd,imm5,tb,Rm): +def A_sreg(obj,Rn,Rd,imm5,tb,Rm): obj.n = env.regs[Rn] obj.d = env.regs[Rd] + if 15 in (Rd,Rn,Rm): raise InstructionError(obj) obj.mnemonic += 'BT' if tb==0 else 'TB' - obj.m = DecodeShift(tb<1,env.regs[Rm],imm5) + obj.m = DecodeShift(tb<1,env.regs[Rm],env.cst(imm5,5)) obj.operands = [obj.d,obj.n,obj.m] obj.type = type_data_processing @ispec("32[ 1111 01 0 1 U R 01 Rn(4) 1111 imm12(12) ]", mnemonic="PLD") -def instr_PLD_imm(obj,U,R,Rn,imm12): +def instr_PLx(obj,U,R,Rn,imm12): obj.n = env.regs[Rn] obj.imm32 = cst(imm12,32) obj.add = (U==1) obj.is_pldw = (R==0) + if obj._is_pldw: obj.mnemonic += 'W' obj.operands = [obj.n,obj.imm32] obj.type = type_cpu_state @ispec("32[ 1111 01 1 1 U R 01 Rn(4) 1111 imm5(5) stype(2) 0 Rm(4) ]", mnemonic="PLD") -def instr_PLD_reg(obj,U,R,Rn,imm5,stype,Rm): +def instr_PLx(obj,U,R,Rn,imm5,stype,Rm): obj.n = env.regs[Rn] - obj.m = DecodeShift(stype,env.regs[Rm],imm5) + obj.m = DecodeShift(stype,env.regs[Rm],env.cst(imm5,5)) + if Rm==15: raise InstructionError(obj) obj.add = (U==1) obj.is_pldw = (R==0) + if obj._is_pldw: obj.mnemonic += 'W' obj.operands = [obj.n,obj.m] obj.type = type_cpu_state @ispec("32[ 1111 0100 U 101 Rn(4) 1111 imm12(12) ]", mnemonic="PLI") -def instr_PLI_imm(obj,U,Rn,imm12): +def instr_PLx(obj,U,Rn,imm12): obj.n = env.regs[Rn] obj.imm32 = cst(imm12,32) obj.add = (U==1) @@ -459,34 +530,43 @@ def instr_PLI_imm(obj,U,Rn,imm12): obj.type = type_cpu_state @ispec("32[ 1111 0110 U 101 Rn(4) 1111 imm5(5) stype(2) 0 Rm(4) ]", mnemonic="PLI") -def instr_PLI_reg(obj,U,Rn,imm5,stype,Rm): +def instr_PLx(obj,U,Rn,imm5,stype,Rm): obj.n = env.regs[Rn] - obj.m = DecodeShift(stype,env.regs[Rm],imm5) + obj.m = DecodeShift(stype,env.regs[Rm],env.cst(imm5,5)) obj.add = (U==1) obj.operands = [obj.n,obj.m] obj.type = type_cpu_state +@ispec("32[ .cond(4) 010100101101 Rt(4) 000000000100 ]", mnemonic="PUSH") @ispec("32[ .cond(4) 010010011101 Rt(4) 000000000100 ]", mnemonic="POP") -def instr_POP(obj,Rt): +def A_reglist(obj,Rt): obj.t = env.regs[Rt] + if Rt==13: raise InstructionError(obj) obj.registers = [obj.t] - obj.operands = obj.registers + obj.operands = [obj.registers] obj.type = type_data_processing + if obj.mnemonic=='POP': + if env.pc in obj.registers: obj.type = type_control_flow @ispec("32[ .cond(4) 10010010 1101 ~register_list(16) ]", mnemonic="PUSH") -def instr_PUSH(obj,register_list): +@ispec("32[ .cond(4) 10001011 1101 ~register_list(16) ]", mnemonic="POP") +def A_reglist(obj,register_list): obj.registers = [env.regs[i] for i,r in enumerate(register_list) if r==1] - obj.operands = obj.registers + if env.regs[13] in obj.registers: raise InstructionError(obj) + obj.operands = [obj.registers] obj.type = type_data_processing + if obj.mnemonic=='POP': + if env.pc in obj.registers: obj.type = type_control_flow @ispec("32[ .cond(4) 00010000 Rn(4) Rd(4) 0000 0101 Rm(4) ]", mnemonic="QADD") @ispec("32[ .cond(4) 00010010 Rn(4) Rd(4) 0000 0101 Rm(4) ]", mnemonic="QSUB") @ispec("32[ .cond(4) 00010100 Rn(4) Rd(4) 0000 0101 Rm(4) ]", mnemonic="QDADD") @ispec("32[ .cond(4) 00010110 Rn(4) Rd(4) 0000 0101 Rm(4) ]", mnemonic="QDSUB") -def instr_Qxxx(obj,Rn,Rd,Rm): +def A_default(obj,Rn,Rd,Rm): obj.n = env.regs[Rn] obj.d = env.regs[Rd] obj.m = env.regs[Rm] + if 15 in (Rd,Rm,Rn): raise InstructionError(obj) obj.operands = [obj.d,obj.m,obj.n] obj.type = type_data_processing @@ -527,10 +607,11 @@ def instr_Qxxx(obj,Rn,Rd,Rm): @ispec("32[ .cond(4) 01100101 Rn(4) Rd(4) 1111 0101 Rm(4) ]", mnemonic="USAX") @ispec("32[ .cond(4) 01100101 Rn(4) Rd(4) 1111 0111 Rm(4) ]", mnemonic="USUB16") @ispec("32[ .cond(4) 01100101 Rn(4) Rd(4) 1111 1111 Rm(4) ]", mnemonic="USUB8") -def instr_arithm_invert_n_m(obj,Rn,Rd,Rm): +def A_default(obj,Rn,Rd,Rm): obj.n = env.regs[Rn] obj.d = env.regs[Rd] obj.m = env.regs[Rm] + if 15 in (Rd,Rm,Rn): raise InstructionError(obj) obj.operands = [obj.d,obj.n,obj.m] obj.type = type_data_processing @@ -538,20 +619,22 @@ def instr_arithm_invert_n_m(obj,Rn,Rd,Rm): @ispec("32[ .cond(4) 01101011 1111 Rd(4) 1111 0011 Rm(4) ]", mnemonic="REV") @ispec("32[ .cond(4) 01101011 1111 Rd(4) 1111 1011 Rm(4) ]", mnemonic="REV16") @ispec("32[ .cond(4) 01101111 1111 Rd(4) 1111 1011 Rm(4) ]", mnemonic="REVSH") -def instr_RBIT(obj,Rd,Rm): +def A_default(obj,Rd,Rm): obj.d = env.regs[Rd] obj.m = env.regs[Rm] + if 15 in (Rd,Rm): raise InstructionError(obj) obj.operands = [obj.d,obj.m] obj.type = type_data_processing @ispec("32[ .cond(4) 01111 01 widthm1(5) Rd(4) lsb(5) 101 Rn(4) ]", mnemonic="SBFX") @ispec("32[ .cond(4) 01111 11 widthm1(5) Rd(4) lsb(5) 101 Rn(4) ]", mnemonic="UBFX") -def instr_SBFX(obj,widthm1,Rd,lsb,Rn): +def A_default(obj,widthm1,Rd,lsb,Rn): obj.d = env.regs[Rd] obj.n = env.regs[Rn] + if 15 in (Rd,Rn): raise InstructionError(obj) obj.lsbit = env.cst(lsb,5) obj.widthminus1 = env.cst(widthm1,5) - obj.operands = [obj.d,obj.n] + obj.operands = [obj.d,obj.n, obj.lsbit, obj.widthminus1+1] obj.type = type_data_processing @ispec("32[ 1111 00010000 000 1 000000 E 0 0000 0000 ]", mnemonic="SETEND") @@ -575,11 +658,12 @@ def instr_SETEND(obj,E): @ispec("32[ .cond(4) 01110101 Rd(4) Ra(4) Rm(4) 1101 Rn(4) ]", mnemonic="SMMLS") @ispec("32[ .cond(4) 01110101 Rd(4) Ra(4) Rm(4) 1111 Rn(4) ]", mnemonic="SMMLSR") @ispec("32[ .cond(4) 01111000 Rd(4) Ra(4) Rm(4) 0001 Rn(4) ]", mnemonic="USADA8") -def instr_SMLAxy(obj,Rd,Ra,Rm,Rn): +def A_default(obj,Rd,Ra,Rm,Rn): obj.d = env.regs[Rd] obj.n = env.regs[Rn] obj.m = env.regs[Rm] obj.a = env.regs[Ra] + if 15 in (Rd,Rn,Rm,Ra): raise InstructionError(obj) obj.operands = [obj.d,obj.n,obj.m,obj.a] obj.type = type_data_processing @@ -587,13 +671,14 @@ def instr_SMLAxy(obj,Rd,Ra,Rm,Rn): @ispec("32[ .cond(4) 0000110 S RdHi(4) RdLo(4) Rm(4) 1001 Rn(4) ]", mnemonic="SMULL") @ispec("32[ .cond(4) 0000101 S RdHi(4) RdLo(4) Rm(4) 1001 Rn(4) ]", mnemonic="UMLAL") @ispec("32[ .cond(4) 0000100 S RdHi(4) RdLo(4) Rm(4) 1001 Rn(4) ]", mnemonic="UMULL") -def instr_SMLAL(obj,S,RdHi,RdLo,Rm,Rn): +def A_default(obj,S,RdHi,RdLo,Rm,Rn): obj.setflags = (S==1) obj.dLo = env.regs[RdLo] obj.dHi = env.regs[RdHi] obj.m = env.regs[Rm] obj.n = env.regs[Rn] obj.operands = [obj.dLo,obj.dHi,obj.n,obj.m] + if env.pc in obj.operands: raise InstructionError(obj) obj.type = type_data_processing @ispec("32[ .cond(4) 00010100 RdHi(4) RdLo(4) Rm(4) 1000 Rn(4) ]", mnemonic="SMLALBB") @@ -605,12 +690,13 @@ def instr_SMLAL(obj,S,RdHi,RdLo,Rm,Rn): @ispec("32[ .cond(4) 01110100 RdHi(4) RdLo(4) Rm(4) 0101 Rn(4) ]", mnemonic="SMLSLD") @ispec("32[ .cond(4) 01110100 RdHi(4) RdLo(4) Rm(4) 0111 Rn(4) ]", mnemonic="SMLSLDX") @ispec("32[ .cond(4) 00000100 RdHi(4) RdLo(4) Rm(4) 1001 Rn(4) ]", mnemonic="UMAAL") -def instr_SMLALxy(obj,RdHi,RdLo,Rm,Rn): +def A_default(obj,RdHi,RdLo,Rm,Rn): obj.dLo = env.regs[RdLo] obj.dHi = env.regs[RdHi] obj.m = env.regs[Rm] obj.n = env.regs[Rn] obj.operands = [obj.dLo,obj.dHi,obj.n,obj.m] + if env.pc in obj.operands: raise InstructionError(obj) obj.type = type_data_processing @ispec("32[ .cond(4) 01110101 Rd(4) 1111 Rm(4) 0001 Rn(4) ]", mnemonic="SMMUL") @@ -626,44 +712,49 @@ def instr_SMLALxy(obj,RdHi,RdLo,Rm,Rn): @ispec("32[ .cond(4) 00010010 Rd(4) 0000 Rm(4) 1010 Rn(4) ]", mnemonic="SMULWB") @ispec("32[ .cond(4) 00010010 Rd(4) 0000 Rm(4) 1110 Rn(4) ]", mnemonic="SMULWT") @ispec("32[ .cond(4) 01111000 Rd(4) 1111 Rm(4) 0001 Rn(4) ]", mnemonic="USAD8") -def instr_SMMULr(obj,Rd,Rm,Rn): +def A_default(obj,Rd,Rm,Rn): obj.d = env.regs[Rd] obj.n = env.regs[Rn] obj.m = env.regs[Rm] obj.operands = [obj.d,obj.n,obj.m] + if env.pc in obj.operands: raise InstructionError(obj) obj.type = type_data_processing @ispec("32[ .cond(4) 0110101 sat_imm(5) Rd(4) imm5(5) sh 01 Rn(4) ]", mnemonic="SSAT") @ispec("32[ .cond(4) 0110111 sat_imm(5) Rd(4) imm5(5) sh 01 Rn(4) ]", mnemonic="USAT") -def instr_SSAT(obj,sat_imm,Rd,imm5,sh,Rn): +def A_sreg(obj,sat_imm,Rd,imm5,sh,Rn): obj.d = env.regs[Rd] - obj.n = DecodeShift(sh<<1,env.regs[Rn],imm5) + obj.n = DecodeShift(sh<<1,env.regs[Rn],env.cst(imm5,5)) obj.saturate_to = sat_imm+1 obj.operands = [obj.d,obj.saturate_to,obj.n] + if env.pc in obj.operands: raise InstructionError(obj) obj.type = type_data_processing @ispec("32[ .cond(4) 01101010 sat_imm(4) Rd(4) 1111 0001 Rn(4) ]", mnemonic="SSAT16") @ispec("32[ .cond(4) 01101110 sat_imm(4) Rd(4) 1111 0011 Rn(4) ]", mnemonic="USAT16") -def instr_SSAT16(obj,sat_imm,Rd,Rn): +def A_default(obj,sat_imm,Rd,Rn): obj.d = env.regs[Rd] obj.n = env.regs[Rn] obj.saturate_to = sat_imm+1 obj.operands = [obj.d,obj.saturate_to,obj.n] + if env.pc in obj.operands: raise InstructionError(obj) obj.type = type_data_processing @ispec("32[ .cond(4) 1111 imm24(24) ]", mnemonic="SVC") -def instr_SVC(obj,imm24): +def A_default(obj,imm24): obj.imm32 = env.cst(imm24,32) obj.operands = [obj.imm32] obj.type = type_cpu_state @ispec("32[ .cond(4) 00010 0 00 Rn(4) Rt(4) 0000 1001 Rt2(4) ]", mnemonic="SWP") @ispec("32[ .cond(4) 00010 1 00 Rn(4) Rt(4) 0000 1001 Rt2(4) ]", mnemonic="SWPB") -def instr_SWP(obj,Rn,Rt,Rt2): +def A_default(obj,Rn,Rt,Rt2): obj.n = env.regs[Rn] obj.t = env.regs[Rt] obj.t2 = env.regs[Rt2] obj.operands = [obj.t,obj.t2,obj.n] + if env.pc in obj.operands: raise InstructionError(obj) + if (Rn==Rt) or (Rn==Rt2): raise InstructionError(obj) obj.type = type_data_processing @ispec("32[ .cond(4) 01101000 Rn(4) Rd(4) rotate(2) 00 0111 Rm(4) ]", mnemonic="SXTAB16") @@ -672,11 +763,12 @@ def instr_SWP(obj,Rn,Rt,Rt2): @ispec("32[ .cond(4) 01101100 Rn(4) Rd(4) rotate(2) 00 0111 Rm(4) ]", mnemonic="UXTAB16") @ispec("32[ .cond(4) 01101110 Rn(4) Rd(4) rotate(2) 00 0111 Rm(4) ]", mnemonic="UXTAB") @ispec("32[ .cond(4) 01101111 Rn(4) Rd(4) rotate(2) 00 0111 Rm(4) ]", mnemonic="UXTAH") -def instr_SXTA__(obj,Rn,Rd,rotate,Rm): +def A_default(obj,Rn,Rd,rotate,Rm): obj.n = env.regs[Rn] obj.d = env.regs[Rd] - obj.m = ROR(env.regs[Rm],rotate*8) + obj.m = env.ror(env.regs[Rm],rotate*8) obj.operands = [obj.d,obj.n,obj.m] + if env.pc in obj.operands: raise InstructionError(obj) obj.type = type_data_processing @ispec("32[ .cond(4) 01101000 1111 Rd(4) rotate(2) 00 0111 Rm(4) ]", mnemonic="SXTB16") @@ -685,9 +777,10 @@ def instr_SXTA__(obj,Rn,Rd,rotate,Rm): @ispec("32[ .cond(4) 01101100 1111 Rd(4) rotate(2) 00 0111 Rm(4) ]", mnemonic="UXTB16") @ispec("32[ .cond(4) 01101110 1111 Rd(4) rotate(2) 00 0111 Rm(4) ]", mnemonic="UXTB") @ispec("32[ .cond(4) 01101111 1111 Rd(4) rotate(2) 00 0111 Rm(4) ]", mnemonic="UXTH") -def instr_SXT__(obj,Rd,rotate,Rm): +def A_default(obj,Rd,rotate,Rm): obj.d = env.regs[Rd] - obj.m = ROR(env.regs[Rm],rotate*8) + obj.m = env.ror(env.regs[Rm],rotate*8) obj.operands = [obj.d,obj.m] + if env.pc in obj.operands: raise InstructionError(obj) obj.type = type_data_processing diff --git a/amoco/arch/arm/v7/spec_thumb.py b/amoco/arch/arm/v7/spec_thumb.py index a2a4653..a942f48 100644 --- a/amoco/arch/arm/v7/spec_thumb.py +++ b/amoco/arch/arm/v7/spec_thumb.py @@ -28,180 +28,204 @@ @ispec("16[ 010000 0111 Rm(3) Rdn(3) ]", mnemonic="ROR") @ispec("16[ 010000 1100 Rm(3) Rdn(3) ]", mnemonic="ORR") @ispec("16[ 010000 1110 Rm(3) Rdn(3) ]", mnemonic="BIC") -def T1_ADC_r(obj,Rm,Rdn): +def A_default(obj,Rm,Rdn): obj.setflags = ~InITBlock(env.internals['itstate']) obj.n = env.regs[Rdn] obj.d = obj.n obj.m = env.regs[Rm] obj.operands = [obj.d,obj.n,obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 000 11 1 0 imm3(3) Rn(3) Rd(3) ]", mnemonic="ADD") @ispec("16[ 000 11 1 1 imm3(3) Rn(3) Rd(3) ]", mnemonic="SUB") -def T1_ADD_i(obj,imm3,Rn,Rd): +def A_default(obj,imm3,Rn,Rd): obj.setflags = ~InITBlock(env.internals['itstate']) obj.n = env.regs[Rn] obj.d = env.regs[Rd] obj.imm32 = env.cst(imm3,32) obj.operands = [obj.d,obj.n,obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 001 10 Rdn(3) imm8(8) ]", mnemonic="ADD") @ispec("16[ 001 11 Rdn(3) imm8(8) ]", mnemonic="SUB") -def T2_ADD_i(obj,Rdn,imm8): +def A_default(obj,Rdn,imm8): obj.setflags = ~InITBlock(env.internals['itstate']) obj.n = env.regs[Rdn] obj.d = obj.n obj.imm32 = env.cst(imm8,32) obj.operands = [obj.d,obj.n,obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 000 11 0 0 Rm(3) Rn(3) Rd(3) ]", mnemonic="ADD") @ispec("16[ 000 11 0 1 Rm(3) Rn(3) Rd(3) ]", mnemonic="SUB") -def T1_ADD_r(obj,Rm,Rn,Rd): +def A_default(obj,Rm,Rn,Rd): obj.setflags = ~InITBlock(env.internals['itstate']) obj.n = env.regs[Rn] obj.d = env.regs[Rd] obj.m = env.regs[Rm] obj.operands = [obj.d,obj.n,obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 010001 00 DN Rm(4) Rdn(3) ]", mnemonic="ADD") -def T2_ADD_r(obj,DN,Rm,Rdn): +def A_default(obj,DN,Rm,Rdn): obj.setflags = False obj.n = env.regs[DN<<3+Rdn] obj.d = obj.n obj.m = env.regs[Rm] obj.operands = [obj.d,obj.n,obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 1010 1 Rd(3) imm8(8) ]", mnemonic="ADD") -def T1_ADD_SP_i(obj,Rd,imm8): +def A_default(obj,Rd,imm8): obj.d = env.regs[Rd] obj.n = env.sp obj.imm32 = env.cst(imm8<<2,32) obj.operands = [obj.d,obj.n,obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 1011 0000 0 imm7(7) ]", mnemonic="ADD") @ispec("16[ 1011 0000 1 imm7(7) ]", mnemonic="SUB") -def T2_ADD_SP_i(obj,imm7): +def A_default(obj,imm7): obj.d = env.sp obj.n = env.sp obj.imm32 = env.cst(imm7<<2,32) obj.operands = [obj.d,obj.n,obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 01000100 DM 1101 Rdm(3) ]", mnemonic="ADD") -def T1_ADD_SP_r(obj,DM,Rdm): +def A_default(obj,DM,Rdm): obj.d = env.regs[DM<<3+Rdm] obj.n = env.sp obj.m = obj.d obj.operands = [obj.d,obj.n,obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 01000100 1 Rm(4) 101 ]", mnemonic="ADD") -def T2_ADD_SP_r(obj,Rm): +def A_default(obj,Rm): obj.d = env.sp obj.n = env.sp obj.m = env.regs[Rm] obj.operands = [obj.d,obj.n,obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 1010 0 Rd(3) imm8(8) ]", mnemonic="ADR") -def T1_ADR(obj,Rd,imm8): +def A_adr(obj,Rd,imm8): obj.d = env.regs[Rd] obj.imm32 = env.cst(imm8<<2,32) obj.operands = [obj.d,obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 000 10 imm5(5) Rm(3) Rd(3) ]", mnemonic="ASR") @ispec("16[ 000 00 imm5(5) Rm(3) Rd(3) ]", mnemonic="LSL") @ispec("16[ 000 01 imm5(5) Rm(3) Rd(3) ]", mnemonic="LSR") -def T1_ASR_i(obj,imm5,Rm,Rd): +def A_default(obj,imm5,Rm,Rd): obj.setflags = ~InITBlock(env.internals['itstate']) obj.d = env.regs[Rd] obj.m = env.regs[Rm] - obj.imm5 = imm5 + obj.imm5 = env.cst(imm5,5) obj.operands = [obj.d,obj.m,obj.imm5] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 1101 .cond(4) imm8(8) ]", mnemonic="B") -def T1_B(obj,imm8): +def A_label(obj,imm8): obj.imm32 = env.cst(imm8<<1,9).signextend(32) obj.operands = [obj.imm32] obj.type = type_control_flow + obj.cond = env.CONDITION_AL @ispec("16[ 11100 imm11(11) ]", mnemonic="B") -def T2_B(obj,imm11): +def A_label(obj,imm11): obj.imm32 = env.cst(imm11<<1,12).signextend(32) obj.operands = [obj.imm32] obj.type = type_control_flow + obj.cond = env.CONDITION_AL @ispec("16[ 1101 1110 imm8(8) ]", mnemonic="BKPT") @ispec("16[ 1101 1111 imm8(8) ]", mnemonic="SVC") -def T1_BKPT(obj,imm8): +def A_default(obj,imm8): obj.imm32 = env.cst(imm8,32) obj.operands = [obj.imm32] obj.type = type_cpu_state + obj.cond = env.CONDITION_AL @ispec("16[ 010001 11 0 Rm(4) 000 ]", mnemonic="BX") @ispec("16[ 010001 11 1 Rm(4) 000 ]", mnemonic="BLX") -def T1_BLX_r(obj,Rm): +def A_default(obj,Rm): obj.m = env.regs[Rm] + if Rm==15 and obj.mnemonic=='BLX': raise InstructionError(obj) obj.operands = [obj.m] obj.type = type_control_flow + obj.cond = env.CONDITION_AL @ispec("16[ 1011 0 0 #i 1 #imm5(5) Rn(3) ]", mnemonic="CBZ") @ispec("16[ 1011 1 0 #i 1 #imm5(5) Rn(3) ]", mnemonic="CBNZ") -def T1_CBNZ_CBZ(obj,i,imm5,Rn): +def A_default(obj,i,imm5,Rn): obj.n = env.regs[Rn] obj.imm32 = env.cst(int(i+imm5+'0',2),32) obj.operands = [obj.n, obj.imm32] obj.type = type_control_flow + obj.cond = env.CONDITION_AL @ispec("16[ 010000 1011 Rm(3) Rn(3) ]", mnemonic="CMN") @ispec("16[ 010000 1010 Rm(3) Rn(3) ]", mnemonic="CMP") @ispec("16[ 010000 1000 Rm(3) Rn(3) ]", mnemonic="TST") -def T1_CMN_r(obj,i,Rm,Rn): +def A_default(obj,i,Rm,Rn): obj.n = env.regs[Rn] obj.m = env.regs[Rm] obj.operands = [obj.n, obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 001 01 Rn(3) imm8(8) ]", mnemonic="CMP") -def T1_CMP_i(obj,Rn,imm8): +def A_default(obj,Rn,imm8): obj.n = env.regs[Rn] obj.imm32 = env.cst(imm8,32) obj.operands = [obj.n, obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 010001 01 N Rm(4) Rn(3) ]", mnemonic="CMP") -def T2_CMP_r(obj,N,Rm,Rn): +def A_default(obj,N,Rm,Rn): obj.n = env.regs[N<<3+Rn] obj.m = env.regs[Rm] obj.operands = [obj.n, obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 1011 1111 .firstcond(4) .mask(4) ]", mnemonic="IT") -def T1_IT(obj): +def A_default(obj): obj.type = type_cpu_state + obj.cond = env.CONDITION_AL @ispec("16[ 1100 1 Rn(3) ~register_list(8) ]", mnemonic="LDM") -def T1_LDM(obj,Rn,register_list): +def A_reglist(obj,Rn,register_list): obj.n = env.regs[Rn] obj.registers = [env.regs[i] for i,r in enumerate(register_list) if r==1] + if len(obj.registers)<1: raise InstructionError(obj) obj.wback = (obj.n in obj.registers) obj.operands = [obj.n, obj.registers] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 1100 0 Rn(3) ~register_list(8) ]", mnemonic="STM") -def T1_STM(obj,Rn,register_list): +def A_reglist(obj,Rn,register_list): obj.n = env.regs[Rn] obj.registers = [env.regs[i] for i,r in enumerate(register_list) if r==1] obj.wback = True obj.operands = [obj.n, obj.registers] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 011 1 1 imm5(5) Rn(3) Rt(3) ]", mnemonic="LDRB",_s=0) @ispec("16[ 100 0 1 imm5(5) Rn(3) Rt(3) ]", mnemonic="LDRH",_s=1) @@ -209,7 +233,7 @@ def T1_STM(obj,Rn,register_list): @ispec("16[ 011 1 0 imm5(5) Rn(3) Rt(3) ]", mnemonic="STRB",_s=0) @ispec("16[ 100 0 0 imm5(5) Rn(3) Rt(3) ]", mnemonic="STRH",_s=1) @ispec("16[ 011 0 0 imm5(5) Rn(3) Rt(3) ]", mnemonic="STR", _s=2) -def T1_LDRx(obj,imm5,Rn,Rt,_s): +def A_deref(obj,imm5,Rn,Rt,_s): obj.n = env.regs[Rn] obj.t = env.regs[Rt] obj.imm32 = env.cst(imm5<<_s,32) @@ -218,10 +242,11 @@ def T1_LDRx(obj,imm5,Rn,Rt,_s): obj.wback = False obj.operands = [obj.t, obj.n, obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 1001 1 Rt(3) imm8(8) ]", mnemonic="LDR") @ispec("16[ 1001 0 Rt(3) imm8(8) ]", mnemonic="STR") -def T2_LDR(obj,Rt,imm8): +def A_deref(obj,Rt,imm8): obj.n = env.sp obj.t = env.regs[Rt] obj.imm32 = env.cst(imm8<<2,32) @@ -230,15 +255,19 @@ def T2_LDR(obj,Rt,imm8): obj.wback = False obj.operands = [obj.t, obj.n, obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 01001 Rt(3) imm8(8) ]", mnemonic="LDR") -def T1_LDR_literal(obj,Rt,imm8): +def A_deref(obj,Rt,imm8): obj.n = env.pc obj.t = env.regs[Rt] obj.imm32 = env.cst(imm8<<2,32) + obj.index = True obj.add = True + obj.wback = False obj.operands = [obj.t, obj.n, obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 0101 100 Rm(3) Rn(3) Rt(3) ]", mnemonic="LDR") @ispec("16[ 0101 110 Rm(3) Rn(3) Rt(3) ]", mnemonic="LDRB") @@ -248,7 +277,7 @@ def T1_LDR_literal(obj,Rt,imm8): @ispec("16[ 0101 000 Rm(3) Rn(3) Rt(3) ]", mnemonic="STR") @ispec("16[ 0101 010 Rm(3) Rn(3) Rt(3) ]", mnemonic="STRB") @ispec("16[ 0101 001 Rm(3) Rn(3) Rt(3) ]", mnemonic="STRH") -def T1_LDR_r(obj,Rm,Rn,Rt): +def A_deref(obj,Rm,Rn,Rt): obj.n = env.regs[Rn] obj.t = env.regs[Rt] obj.m = env.regs[Rm] @@ -257,22 +286,25 @@ def T1_LDR_r(obj,Rm,Rn,Rt): obj.wback = False obj.operands = [obj.t, obj.n, obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 001 00 Rd(3) imm8(8) ]", mnemonic="MOV") -def T1_MOV_i(obj,Rd,imm8): +def A_default(obj,Rd,imm8): obj.setflags = ~InITBlock(env.internals['itstate']) obj.d = env.regs[Rd] obj.imm32 = env.cst(imm8,32) obj.operands = [obj.d, obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 010001 10 D Rm(4) Rd(3) ]", mnemonic="MOV") -def T1_MOV_r(obj,D,Rm,Rd): +def A_default(obj,D,Rm,Rd): obj.setflags = False obj.d = env.regs[D<<3+Rd] obj.m = env.regs[Rm] obj.operands = [obj.d, obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 000 00 00000 Rm(3) Rd(3) ]", mnemonic="MOV") @ispec("16[ 1011 1010 00 Rm(3) Rd(3) ]", mnemonic="REV") @@ -282,64 +314,72 @@ def T1_MOV_r(obj,D,Rm,Rd): @ispec("16[ 1011 0010 00 Rm(3) Rd(3) ]", mnemonic="SXTH", rotation=0) @ispec("16[ 1011 0010 11 Rm(3) Rd(3) ]", mnemonic="UXTB", rotation=0) @ispec("16[ 1011 0010 10 Rm(3) Rd(3) ]", mnemonic="UXTH", rotation=0) -def T2_MOV_r(obj,Rm,Rd): +def A_default(obj,Rm,Rd): obj.setflags = True obj.d = env.regs[Rd] obj.m = env.regs[Rm] obj.operands = [obj.d, obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 010000 1101 Rn(3) Rdm(3) ]", mnemonic="MUL") -def T1_MUL(obj,Rn,Rdm): +def A_default(obj,Rn,Rdm): obj.setflags = ~InITBlock(env.internals['itstate']) obj.d = env.regs[Rdm] obj.n = env.regs[Rn] obj.m = obj.d obj.operands = [obj.d,obj.n,obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 010000 1111 Rm(3) Rd(3) ]", mnemonic="MVN") -def T1_MVN_r(obj,Rm,Rd): +def A_default(obj,Rm,Rd): obj.setflags = ~InITBlock(env.internals['itstate']) obj.d = env.regs[Rd] obj.m = env.regs[Rm] obj.operands = [obj.d, obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 1011 1111 0000 0000 ]", mnemonic="NOP") @ispec("16[ 1011 1111 0100 0000 ]", mnemonic="SEV") @ispec("16[ 1011 1111 0010 0000 ]", mnemonic="WFE") @ispec("16[ 1011 1111 0011 0000 ]", mnemonic="WFI") @ispec("16[ 1011 1111 0001 0000 ]", mnemonic="YIELD") -def T1_NOP(obj): +def A_default(obj): obj.type = type_cpu_state + obj.cond = env.CONDITION_AL @ispec("16[ 1011 1 10 #P #register_list(8) ]", mnemonic="POP") -def T1_POP(obj,P,register_list): +def A_reglist(obj,P,register_list): obj.registers = [env.regs[i] for i,r in enumerate(register_list[::-1]+'0'*7+P) if r=='1'] obj.operands = [obj.registers] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 1011 0 10 #M #register_list(8) ]", mnemonic="PUSH") -def T1_PUSH(obj,M,register_list): +def A_reglist(obj,M,register_list): obj.registers = [env.regs[i] for i,r in enumerate(register_list[::-1]+'0'*6+M+'0') if r=='1'] obj.operands = [obj.registers] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 010000 1001 Rn(3) Rd(3) ]", mnemonic="RSB") -def T1_RSB(obj,Rn,Rd): +def A_default(obj,Rn,Rd): obj.setflags = ~InITBlock(env.internals['itstate']) obj.d = env.regs[Rd] obj.n = env.regs[Rn] obj.imm32 = env.cst(0,32) obj.operands = [obj.d,obj.n,obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL @ispec("16[ 1011 0110 010 1 E 000 ]", mnemonic="SETEND") -def T1_SETEND(obj,E): +def instr_SETEND(obj,E): obj.set_bigend = (E==1) obj.operands = [obj.set_bigend] obj.type = type_cpu_state + obj.cond = env.CONDITION_AL # add THUMB-2 instructions: from amoco.arch.arm.v7 import spec_thumb2 diff --git a/amoco/arch/arm/v7/spec_thumb2.py b/amoco/arch/arm/v7/spec_thumb2.py index 98c46f5..ea6ff35 100644 --- a/amoco/arch/arm/v7/spec_thumb2.py +++ b/amoco/arch/arm/v7/spec_thumb2.py @@ -11,231 +11,266 @@ from .utils import * #------------------------------------------------------ -# amoco THUMB(1&2) instruction specs: +# amoco THUMB2 instruction specs: #------------------------------------------------------ ISPECS = [] -@ispec("32[ 11110 #i 0 0000 S Rn(4) 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="AND") -@ispec("32[ 11110 #i 0 0001 S Rn(4) 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="BIC") -@ispec("32[ 11110 #i 0 0010 S Rn(4) 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="ORR") -@ispec("32[ 11110 #i 0 0011 S Rn(4) 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="ORN") -@ispec("32[ 11110 #i 0 0100 S Rn(4) 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="EOR") -@ispec("32[ 11110 #i 0 1000 S Rn(4) 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="ADD") -@ispec("32[ 11110 #i 0 1010 S Rn(4) 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="ADC") -@ispec("32[ 11110 #i 0 1011 S Rn(4) 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="SBC") -@ispec("32[ 11110 #i 0 1101 S Rn(4) 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="SUB") -@ispec("32[ 11110 #i 0 1110 S Rn(4) 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="RSB") -def Tx_immediate(obj,i,S,Rn,imm3,Rd,imm8): +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 0 0000 S Rn(4) ]", mnemonic="AND") +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 0 0001 S Rn(4) ]", mnemonic="BIC") +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 0 0010 S Rn(4) ]", mnemonic="ORR") +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 0 0011 S Rn(4) ]", mnemonic="ORN") +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 0 0100 S Rn(4) ]", mnemonic="EOR") +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 0 1000 S Rn(4) ]", mnemonic="ADD") +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 0 1010 S Rn(4) ]", mnemonic="ADC") +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 0 1011 S Rn(4) ]", mnemonic="SBC") +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 0 1101 S Rn(4) ]", mnemonic="SUB") +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 0 1110 S Rn(4) ]", mnemonic="RSB") +def A_default(obj,i,S,Rn,imm3,Rd,imm8): obj.setflags = (S==1) obj.n = env.regs[Rn] obj.d = env.regs[Rd] + if BadReg(Rd) or Rn==15: raise InstructionError(obj) obj.imm32 = ThumbExpandImm(i+imm3+imm8) obj.operands = [obj.d,obj.n,obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11110 #i 1 0000 0 Rn(4) 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="ADD") -@ispec("32[ 11110 #i 1 0101 0 Rn(4) 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="SUB") -def T4_ADD_i(obj,i,Rn,imm3,Rd,imm8): +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 1 0000 0 Rn(4) ]", mnemonic="ADD") +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 1 0101 0 Rn(4) ]", mnemonic="SUB") +def A_default(obj,i,Rn,imm3,Rd,imm8): obj.setflags = False obj.n = env.regs[Rn] obj.d = env.regs[Rd] + if BadReg(Rd) : raise InstructionError(obj) obj.imm32 = ThumbExpandImm(i+imm3+imm8) obj.operands = [obj.d,obj.n,obj.imm32] obj.type = type_data_processing - -@ispec("32[ 11101 01 0000 S Rn(4) 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) ]", mnemonic="AND") -@ispec("32[ 11101 01 0001 S Rn(4) 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) ]", mnemonic="BIC") -@ispec("32[ 11101 01 0010 S Rn(4) 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) ]", mnemonic="ORR") -@ispec("32[ 11101 01 0011 S Rn(4) 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) ]", mnemonic="ORN") -@ispec("32[ 11101 01 0100 S Rn(4) 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) ]", mnemonic="EOR") -@ispec("32[ 11101 01 1000 S Rn(4) 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) ]", mnemonic="ADD") -@ispec("32[ 11101 01 1010 S Rn(4) 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) ]", mnemonic="ADC") -@ispec("32[ 11101 01 1101 S Rn(4) 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) ]", mnemonic="SUB") -@ispec("32[ 11101 01 1110 S Rn(4) 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) ]", mnemonic="RSB") -@ispec("32[ 11101 01 1011 S Rn(4) 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) ]", mnemonic="SBC") -def Tx_register(obj,S,Rn,imm3,Rd,imm2,stype,Rm): + obj.cond = env.CONDITION_AL + +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) 11101 01 0000 S Rn(4) ]", mnemonic="AND") +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) 11101 01 0001 S Rn(4) ]", mnemonic="BIC") +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) 11101 01 0010 S Rn(4) ]", mnemonic="ORR") +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) 11101 01 0011 S Rn(4) ]", mnemonic="ORN") +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) 11101 01 0100 S Rn(4) ]", mnemonic="EOR") +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) 11101 01 1000 S Rn(4) ]", mnemonic="ADD") +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) 11101 01 1010 S Rn(4) ]", mnemonic="ADC") +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) 11101 01 1101 S Rn(4) ]", mnemonic="SUB") +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) 11101 01 1110 S Rn(4) ]", mnemonic="RSB") +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) stype(2) Rm(4) 11101 01 1011 S Rn(4) ]", mnemonic="SBC") +def A_sreg(obj,S,Rn,imm3,Rd,imm2,stype,Rm): obj.setflags = (S==1) obj.n = env.regs[Rn] obj.d = env.regs[Rd] obj.m = DecodeShift(stype,env.regs[Rm],imm3<<2+imm2) + if Rn==15 or BadReg(Rd) or BadReg(Rm): raise InstructionError(obj) obj.operands = [obj.d,obj.n,obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11110 #i 10101 0 1111 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="ADR", add=False ) -@ispec("32[ 11110 #i 10000 0 1111 0 #imm3(3) Rd(4) #imm8(8) ]", mnemonic="ADR", add=True ) -def T23_ADR(obj,i,imm3,Rd,imm8): +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 10101 0 1111 ]", mnemonic="ADR", add=False ) +@ispec("32[ 0 #imm3(3) Rd(4) #imm8(8) 11110 #i 10000 0 1111 ]", mnemonic="ADR", add=True ) +def A_adr(obj,i,imm3,Rd,imm8): obj.d = env.regs[Rd] + if BadReg(Rd) : raise InstructionError(obj) obj.imm32 = ThumbExpandImm(i+imm3+imm8) obj.operands = [obj.d,obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11101 01 0010 S 1111 0 imm3(3) Rd(4) imm2(2) 10 Rm(4) ]", mnemonic="ASR") -@ispec("32[ 11101 01 0010 S 1111 0 imm3(3) Rd(4) imm2(2) 00 Rm(4) ]", mnemonic="LSL") -@ispec("32[ 11101 01 0010 S 1111 0 imm3(3) Rd(4) imm2(2) 01 Rm(4) ]", mnemonic="LSR") -@ispec("32[ 11101 01 0010 S 1111 0 imm3(3) Rd(4) imm2(2) 11 Rm(4) ]", mnemonic="ROR") -def T2_ASR_i(obj,S,imm3,Rd,imm2,Rm): +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) 10 Rm(4) 11101 01 0010 S 1111 ]", mnemonic="ASR") +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) 00 Rm(4) 11101 01 0010 S 1111 ]", mnemonic="LSL") +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) 01 Rm(4) 11101 01 0010 S 1111 ]", mnemonic="LSR") +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) 11 Rm(4) 11101 01 0010 S 1111 ]", mnemonic="ROR") +def A_default(obj,S,imm3,Rd,imm2,Rm): obj.setflags = (S==1) obj.d = env.regs[Rd] obj.m = env.regs[Rm] - obj.imm5 = imm3<<2+imm2 + if BadReg(Rd) or BadReg(Rm): raise InstructionError(obj) + obj.imm5 = env.cst(imm3<<2+imm2,5) obj.operands = [obj.d,obj.n,obj.imm5] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11111 010 0 10 S Rn(4) 1111 Rd(4) 0 000 Rm(4) ]", mnemonic="ASR") -@ispec("32[ 11111 010 0 00 S Rn(4) 1111 Rd(4) 0 000 Rm(4) ]", mnemonic="LSL") -@ispec("32[ 11111 010 0 01 S Rn(4) 1111 Rd(4) 0 000 Rm(4) ]", mnemonic="LSR") -@ispec("32[ 11111 010 0 11 S Rn(4) 1111 Rd(4) 0 000 Rm(4) ]", mnemonic="ROR") -def T2_ASR_r(obj,S,Rn,Rd,Rm): +@ispec("32[ 1111 Rd(4) 0 000 Rm(4) 11111 010 0 10 S Rn(4) ]", mnemonic="ASR") +@ispec("32[ 1111 Rd(4) 0 000 Rm(4) 11111 010 0 00 S Rn(4) ]", mnemonic="LSL") +@ispec("32[ 1111 Rd(4) 0 000 Rm(4) 11111 010 0 01 S Rn(4) ]", mnemonic="LSR") +@ispec("32[ 1111 Rd(4) 0 000 Rm(4) 11111 010 0 11 S Rn(4) ]", mnemonic="ROR") +def A_default(obj,S,Rn,Rd,Rm): obj.setflags = (S==1) obj.d = env.regs[Rd] obj.n = env.regs[Rn] obj.m = env.regs[Rm] + if BadReg(Rd) or BadReg(Rm) or BadReg(Rn): raise InstructionError(obj) obj.operands = [obj.d,obj.n,obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11110 #S .cond(4) #imm6(6) 1 0 #J1 0 #J2 #imm11(11) ]", mnemonic="B") -def T3_B(obj,S,imm6,J1,J2,imm11): +@ispec("32[ 1 0 #J1 0 #J2 #imm11(11) 11110 #S .cond(4) #imm6(6) ]", mnemonic="B") +def A_label(obj,S,imm6,J1,J2,imm11): v = int(S+J2+J1+imm6+imm11+'0',2) obj.imm32 = env.cst(v,21).signextend(32) obj.operands = [obj.imm32] obj.type = type_control_flow -@ispec("32[ 11110 S #imm10(10) 10 J1 1 J2 #imm11(11) ]", mnemonic="B") -@ispec("32[ 11110 S #imm10(10) 11 J1 1 J2 #imm11(11) ]", mnemonic="BL") -def T4_B(obj,S,imm10,J1,J2,imm11): - I1, I2 = str(~(J1^S)), str(~(J2^S)) +@ispec("32[ 10 #J1 1 #J2 #imm11(11) 11110 #S #imm10(10) ]", mnemonic="B") +@ispec("32[ 11 #J1 1 #J2 #imm11(11) 11110 #S #imm10(10) ]", mnemonic="BL") +def A_label(obj,S,imm10,J1,J2,imm11): + I1 = '1' if J1==S else '0' + I2 = '1' if J2==S else '0' v = int(S+I1+I2+imm10+imm11+'0',2) obj.imm32 = env.cst(v,25).signextend(32) obj.operands = [obj.imm32] obj.type = type_control_flow + obj.cond = env.CONDITION_AL -@ispec("32[ 11110 0 11 011 0 1111 0 imm3(3) Rd(4) imm2(2) 0 msb(5) ]", mnemonic="BFC") -def T1_BFC(obj,imm3,Rd,imm2,msb): +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) 0 msb(5) 11110 0 11 011 0 1111 ]", mnemonic="BFC") +def A_bits(obj,imm3,Rd,imm2,msb): obj.d = env.regs[Rd] + if BadReg(Rd) : raise InstructionError(obj) obj.msbit = msb obj.lsbit = imm3<<2+imm2 obj.operands = [obj.d, obj.lsbit, obj.msbit-obj.lsbit+1] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11110 0 11 011 0 Rn(4) 0 imm3(3) Rd(4) imm2(2) 0 msb(5) ]", mnemonic="BFI") -def T1_BFI(obj,Rn,imm3,Rd,imm2,msb): +@ispec("32[ 0 imm3(3) Rd(4) imm2(2) 0 msb(5) 11110 0 11 011 0 Rn(4) ]", mnemonic="BFI") +def A_bits(obj,Rn,imm3,Rd,imm2,msb): obj.d = env.regs[Rd] obj.n = env.regs[Rn] + if BadReg(Rd) or Rn==13: raise InstructionError(obj) obj.msbit = msb obj.lsbit = imm3<<2+imm2 obj.operands = [obj.d, obj.n, obj.lsbit, obj.msbit-obj.lsbit+1] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11110 S #imm10H(10) 11 J1 0 J2 #imm10L(10) 0 ]", mnemonic="BLX") -def T2_BLX(obj,S,imm10H,J1,J2,imm10L): +@ispec("32[ 11 J1 0 J2 #imm10L(10) 0 11110 S #imm10H(10) ]", mnemonic="BLX") +def A_label(obj,S,imm10H,J1,J2,imm10L): I1, I2 = str(~(J1^S)), str(~(J2^S)) v = int(S+I1+I2+imm10H+imm10L+'00',2) obj.imm32 = env.cst(v,25).signextend(32) obj.operands = [obj.imm32] obj.type = type_control_flow + obj.cond = env.CONDITION_AL -@ispec("32[ 11110 0 1111 00 Rm(4) 10 0 0 1111 00000000 ]", mnemonic="BXJ") -def T1_BXJ(obj,Rm): +@ispec("32[ 10 0 0 1111 00000000 11110 0 1111 00 Rm(4) ]", mnemonic="BXJ") +def A_default(obj,Rm): obj.m = env.regs[Rm] obj.operands = [obj.m] obj.type = type_control_flow - -@ispec("32[ 11110 0 111 01 1 1111 10 0 0 1111 0010 1111 ]", mnemonic="CLREX") -@ispec("32[ 11110 0 111 01 0 1111 10 0 0 0000 0000 0000 ]", mnemonic="NOP") -@ispec("32[ 11110 0 111 01 0 1111 10 0 0 0000 0000 0100 ]", mnemonic="SEV") -@ispec("32[ 11110 0 111 01 0 1111 10 0 0 0000 0000 0010 ]", mnemonic="WFE") -@ispec("32[ 11110 0 111 01 0 1111 10 0 0 0000 0000 0011 ]", mnemonic="WFI") -@ispec("32[ 11110 0 111 01 0 1111 10 0 0 0000 0000 0001 ]", mnemonic="YIELD") -def T1_CLREX_NOP(obj): + obj.cond = env.CONDITION_AL + +@ispec("32[ 10 0 0 1111 0010 1111 11110 0 111 01 1 1111 ]", mnemonic="CLREX") +@ispec("32[ 10 0 0 0000 0000 0000 11110 0 111 01 0 1111 ]", mnemonic="NOP") +@ispec("32[ 10 0 0 0000 0000 0100 11110 0 111 01 0 1111 ]", mnemonic="SEV") +@ispec("32[ 10 0 0 0000 0000 0010 11110 0 111 01 0 1111 ]", mnemonic="WFE") +@ispec("32[ 10 0 0 0000 0000 0011 11110 0 111 01 0 1111 ]", mnemonic="WFI") +@ispec("32[ 10 0 0 0000 0000 0001 11110 0 111 01 0 1111 ]", mnemonic="YIELD") +def A_default(obj): obj.type = type_cpu_state - -@ispec("32[ 11111 010 1 011 rm(4) 1111 Rd(4) 1 000 Rm(4) ]", mnemonic="CLZ") -@ispec("32[ 11111 010 1 001 rm(4) 1111 Rd(4) 1 010 Rm(4) ]", mnemonic="RBIT") -@ispec("32[ 11111 010 1 001 rm(4) 1111 Rd(4) 1 000 Rm(4) ]", mnemonic="REV") -@ispec("32[ 11111 010 1 001 rm(4) 1111 Rd(4) 1 001 Rm(4) ]", mnemonic="REV16") -@ispec("32[ 11111 010 1 001 rm(4) 1111 Rd(4) 1 011 Rm(4) ]", mnemonic="REVSH") -def T1_CLZ(obj,rm,Rd,Rm): + obj.cond = env.CONDITION_AL + +@ispec("32[ 1111 Rd(4) 1 000 Rm(4) 11111 010 1 011 rm(4) ]", mnemonic="CLZ") +@ispec("32[ 1111 Rd(4) 1 010 Rm(4) 11111 010 1 001 rm(4) ]", mnemonic="RBIT") +@ispec("32[ 1111 Rd(4) 1 000 Rm(4) 11111 010 1 001 rm(4) ]", mnemonic="REV") +@ispec("32[ 1111 Rd(4) 1 001 Rm(4) 11111 010 1 001 rm(4) ]", mnemonic="REV16") +@ispec("32[ 1111 Rd(4) 1 011 Rm(4) 11111 010 1 001 rm(4) ]", mnemonic="REVSH") +def A_default(obj,rm,Rd,Rm): assert rm==Rm obj.d = env.regs[Rn] obj.m = env.regs[Rm] + if BadReg(Rd) or BadReg(Rm) : raise InstructionError(obj) obj.operands = [obj.d,obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11110 #i 0 1000 1 Rn(4) 0 #imm3(3) 1111 #imm8(8) ]", mnemonic="CMN") -@ispec("32[ 11110 #i 0 1101 1 Rn(4) 0 #imm3(3) 1111 #imm8(8) ]", mnemonic="CMP") -@ispec("32[ 11110 #i 0 0100 1 Rn(4) 0 #imm3(3) 1111 #imm8(8) ]", mnemonic="TEQ") -@ispec("32[ 11110 #i 0 0000 1 Rn(4) 0 #imm3(3) 1111 #imm8(8) ]", mnemonic="TST") -def T1_CMN_i(obj,i,Rn,imm3,imm8): +@ispec("32[ 0 #imm3(3) 1111 #imm8(8) 11110 #i 0 1000 1 Rn(4) ]", mnemonic="CMN") +@ispec("32[ 0 #imm3(3) 1111 #imm8(8) 11110 #i 0 1101 1 Rn(4) ]", mnemonic="CMP") +@ispec("32[ 0 #imm3(3) 1111 #imm8(8) 11110 #i 0 0100 1 Rn(4) ]", mnemonic="TEQ") +@ispec("32[ 0 #imm3(3) 1111 #imm8(8) 11110 #i 0 0000 1 Rn(4) ]", mnemonic="TST") +def A_default(obj,i,Rn,imm3,imm8): obj.n = env.regs[Rn] + if Rn==15: raise InstructionError(obj) obj.imm32 = ThumbExpandImm(i+imm3+imm8) obj.operands = [obj.n, obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11101 01 1000 1 Rn(4) 0 #imm3(3) 1111 #imm2(2) stype(2) Rm(4) ]", mnemonic="CMN") -@ispec("32[ 11101 01 1101 1 Rn(4) 0 #imm3(3) 1111 #imm2(2) stype(2) Rm(4) ]", mnemonic="CMP") -@ispec("32[ 11101 01 0100 1 Rn(4) 0 #imm3(3) 1111 #imm2(2) stype(2) Rm(4) ]", mnemonic="TEQ") -@ispec("32[ 11101 01 0000 1 Rn(4) 0 #imm3(3) 1111 #imm2(2) stype(2) Rm(4) ]", mnemonic="TST") -def T2_CMN_r(obj,i,Rn,imm3,imm2,stype,Rm): +@ispec("32[ 0 #imm3(3) 1111 #imm2(2) stype(2) Rm(4) 11101 01 1000 1 Rn(4) ]", mnemonic="CMN") +@ispec("32[ 0 #imm3(3) 1111 #imm2(2) stype(2) Rm(4) 11101 01 1101 1 Rn(4) ]", mnemonic="CMP") +@ispec("32[ 0 #imm3(3) 1111 #imm2(2) stype(2) Rm(4) 11101 01 0100 1 Rn(4) ]", mnemonic="TEQ") +@ispec("32[ 0 #imm3(3) 1111 #imm2(2) stype(2) Rm(4) 11101 01 0000 1 Rn(4) ]", mnemonic="TST") +def A_sreg(obj,i,Rn,imm3,imm2,stype,Rm): obj.n = env.regs[Rn] obj.m = DecodeShift(stype,env.regs[Rm],imm3<<2+imm2) + if Rn==15 or BadReg(Rm): raise InstructionError(obj) obj.operands = [obj.n, obj.m] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11110 0 111 01 0 1111 10 000 000 1111 .option(4) ]", mnemonic="DBG") -@ispec("32[ 11110 0 111 01 1 1111 10 00 1111 0101 .option(4) ]", mnemonic="DMB") -@ispec("32[ 11110 0 111 01 1 1111 10 00 1111 0100 .option(4) ]", mnemonic="DSB") -@ispec("32[ 11110 0 111 01 1 1111 10 00 1111 0110 .option(4) ]", mnemonic="ISB") -def T1_Dxx(obj): +@ispec("32[ 10 000 000 1111 .option(4) 11110 0 111 01 0 1111 ]", mnemonic="DBG") +@ispec("32[ 10 00 1111 0101 .option(4) 11110 0 111 01 1 1111 ]", mnemonic="DMB") +@ispec("32[ 10 00 1111 0100 .option(4) 11110 0 111 01 1 1111 ]", mnemonic="DSB") +@ispec("32[ 10 00 1111 0110 .option(4) 11110 0 111 01 1 1111 ]", mnemonic="ISB") +def A_default(obj): obj.type = type_cpu_state -@ispec("32[ 11101 00 010 W 1 Rn(4) #P #M 0 #register_list(13) ]", mnemonic="LDM") -@ispec("32[ 11101 00 100 W 1 Rn(4) #P #M 0 #register_list(13) ]", mnemonic="LDMDB") -def T2_LDM(obj,W,Rn,P,M,register_list): +@ispec("32[ #P #M 0 #register_list(13) 11101 00 010 W 1 Rn(4) ]", mnemonic="LDM") +@ispec("32[ #P #M 0 #register_list(13) 11101 00 100 W 1 Rn(4) ]", mnemonic="LDMDB") +def A_reglist(obj,W,Rn,P,M,register_list): obj.n = env.regs[Rn] obj.registers = [env.regs[i] for i,r in enumerate(register_list[::-1]+'0'+M+P) if r=='1'] + if Rn==15 or len(obj.registers)<2 or (P=='1' and M=='1'): raise InstructionError(obj) obj.wback = (W==1) obj.operands = [obj.n, obj.registers] obj.type = type_data_processing + if env.pc in obj.registers: obj.type = type_control_flow + obj.cond = env.CONDITION_AL -@ispec("32[ 11101 00 010 W 0 Rn(4) 0 #M 0 #register_list(13) ]", mnemonic="STM") -@ispec("32[ 11101 00 100 W 0 Rn(4) 0 #M 0 #register_list(13) ]", mnemonic="STMDB") -def T2_STM(obj,W,Rn,M,register_list): +@ispec("32[ 0 #M 0 #register_list(13) 11101 00 010 W 0 Rn(4) ]", mnemonic="STM") +@ispec("32[ 0 #M 0 #register_list(13) 11101 00 100 W 0 Rn(4) ]", mnemonic="STMDB") +def A_reglist(obj,W,Rn,M,register_list): obj.n = env.regs[Rn] obj.registers = [env.regs[i] for i,r in enumerate(register_list[::-1]+'0'+M) if r=='1'] + if Rn==15 or len(obj.registers)<2 : raise InstructionError(obj) obj.wback = (W==1) obj.operands = [obj.n, obj.registers] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11111 00 0 1 10 1 Rn(4) Rt(4) imm12(12) ]", mnemonic="LDR") -@ispec("32[ 11111 00 0 1 00 1 Rn(4) Rt(4) imm12(12) ]", mnemonic="LDRB") -@ispec("32[ 11111 00 0 1 01 1 Rn(4) Rt(4) imm12(12) ]", mnemonic="LDRH") -@ispec("32[ 11111 00 1 1 00 1 Rn(4) Rt(4) imm12(12) ]", mnemonic="LDRSB") -@ispec("32[ 11111 00 1 1 01 1 Rn(4) Rt(4) imm12(12) ]", mnemonic="LDRSH") -@ispec("32[ 11111 00 0 1 10 0 Rn(4) Rt(4) imm12(12) ]", mnemonic="STR") -@ispec("32[ 11111 00 0 1 00 0 Rn(4) Rt(4) imm12(12) ]", mnemonic="STRB") -@ispec("32[ 11111 00 0 1 01 0 Rn(4) Rt(4) imm12(12) ]", mnemonic="STRH") -def T3_LDR(obj,Rn,Rt,imm12): +@ispec("32[ Rt(4) imm12(12) 11111 00 0 1 10 1 Rn(4) ]", mnemonic="LDR") +@ispec("32[ Rt(4) imm12(12) 11111 00 0 1 00 1 Rn(4) ]", mnemonic="LDRB") +@ispec("32[ Rt(4) imm12(12) 11111 00 0 1 01 1 Rn(4) ]", mnemonic="LDRH") +@ispec("32[ Rt(4) imm12(12) 11111 00 1 1 00 1 Rn(4) ]", mnemonic="LDRSB") +@ispec("32[ Rt(4) imm12(12) 11111 00 1 1 01 1 Rn(4) ]", mnemonic="LDRSH") +@ispec("32[ Rt(4) imm12(12) 11111 00 0 1 10 0 Rn(4) ]", mnemonic="STR") +@ispec("32[ Rt(4) imm12(12) 11111 00 0 1 00 0 Rn(4) ]", mnemonic="STRB") +@ispec("32[ Rt(4) imm12(12) 11111 00 0 1 01 0 Rn(4) ]", mnemonic="STRH") +def A_default(obj,Rn,Rt,imm12): obj.n = env.regs[Rn] obj.t = env.regs[Rt] + if Rt==15: raise InstructionError(obj) # see PLDxx obj.imm32 = env.cst(imm12,32) obj.index = True obj.add = True obj.wback = False obj.operands = [obj.t, obj.n, obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11111 00 0 0 10 1 Rn(4) Rt(4) 1 P U W imm8(8) ]", mnemonic="LDR") -@ispec("32[ 11111 00 0 0 00 1 Rn(4) Rt(4) 1 P U W imm8(8) ]", mnemonic="LDRB") -@ispec("32[ 11111 00 0 0 01 1 Rn(4) Rt(4) 1 P U W imm8(8) ]", mnemonic="LDRH") -@ispec("32[ 11111 00 1 0 00 1 Rn(4) Rt(4) 1 P U W imm8(8) ]", mnemonic="LDRSB") -@ispec("32[ 11111 00 1 0 01 1 Rn(4) Rt(4) 1 P U W imm8(8) ]", mnemonic="LDRSH") -@ispec("32[ 11111 00 0 0 10 0 Rn(4) Rt(4) 1 P U W imm8(8) ]", mnemonic="STR") -@ispec("32[ 11111 00 0 0 00 0 Rn(4) Rt(4) 1 P U W imm8(8) ]", mnemonic="STRB") -@ispec("32[ 11111 00 0 0 01 0 Rn(4) Rt(4) 1 P U W imm8(8) ]", mnemonic="STRH") -def T4_LDR(obj,Rn,Rt,P,U,W,imm8): +@ispec("32[ Rt(4) 1 P U W imm8(8) 11111 00 0 0 10 1 Rn(4) ]", mnemonic="LDR") +@ispec("32[ Rt(4) 1 P U W imm8(8) 11111 00 0 0 00 1 Rn(4) ]", mnemonic="LDRB") +@ispec("32[ Rt(4) 1 P U W imm8(8) 11111 00 0 0 01 1 Rn(4) ]", mnemonic="LDRH") +@ispec("32[ Rt(4) 1 P U W imm8(8) 11111 00 1 0 00 1 Rn(4) ]", mnemonic="LDRSB") +@ispec("32[ Rt(4) 1 P U W imm8(8) 11111 00 1 0 01 1 Rn(4) ]", mnemonic="LDRSH") +@ispec("32[ Rt(4) 1 P U W imm8(8) 11111 00 0 0 10 0 Rn(4) ]", mnemonic="STR") +@ispec("32[ Rt(4) 1 P U W imm8(8) 11111 00 0 0 00 0 Rn(4) ]", mnemonic="STRB") +@ispec("32[ Rt(4) 1 P U W imm8(8) 11111 00 0 0 01 0 Rn(4) ]", mnemonic="STRH") +def A_deref(obj,Rn,Rt,P,U,W,imm8): obj.n = env.regs[Rn] obj.t = env.regs[Rt] + if Rt==15: raise InstructionError(obj) # see PLDxx obj.imm32 = env.cst(imm8,32) if P==1 and U==1 and W==0: obj.mnemonic += 'T' @@ -244,44 +279,50 @@ def T4_LDR(obj,Rn,Rt,P,U,W,imm8): else: obj.index = (P==1) obj.wback = (W==1) + if BadReg(Rt) and (Rn==Rt): raise InstructionError(obj) obj.add = (U==1) obj.operands = [obj.t, obj.n, obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11111 00 0 U 10 1 1111 Rt(4) imm12(12) ]", mnemonic="LDR") -@ispec("32[ 11111 00 0 U 00 1 1111 Rt(4) imm12(12) ]", mnemonic="LDRB") -@ispec("32[ 11111 00 0 U 01 1 1111 Rt(4) imm12(12) ]", mnemonic="LDRH") -@ispec("32[ 11111 00 1 U 00 1 1111 Rt(4) imm12(12) ]", mnemonic="LDRSB") -@ispec("32[ 11111 00 1 U 01 1 1111 Rt(4) imm12(12) ]", mnemonic="LDRSH") -def T2_LDR_literal(obj,U,Rt,imm12): +@ispec("32[ Rt(4) imm12(12) 11111 00 0 U 10 1 1111 ]", mnemonic="LDR") +@ispec("32[ Rt(4) imm12(12) 11111 00 0 U 00 1 1111 ]", mnemonic="LDRB") +@ispec("32[ Rt(4) imm12(12) 11111 00 0 U 01 1 1111 ]", mnemonic="LDRH") +@ispec("32[ Rt(4) imm12(12) 11111 00 1 U 00 1 1111 ]", mnemonic="LDRSB") +@ispec("32[ Rt(4) imm12(12) 11111 00 1 U 01 1 1111 ]", mnemonic="LDRSH") +def A_deref(obj,U,Rt,imm12): obj.n = env.pc obj.t = env.regs[Rt] + if Rt==15: raise InstructionError(obj) # see PLDxx obj.imm32 = env.cst(imm12,32) obj.add = (U==1) obj.operands = [obj.t, obj.n, obj.imm32] obj.type = type_data_processing + obj.cond = env.CONDITION_AL -@ispec("32[ 11111 00 0 0 10 1 Rn(4) Rt(4) 0 00000 imm2(2) Rm(4) ]", mnemonic="LDR") -@ispec("32[ 11111 00 0 0 00 1 Rn(4) Rt(4) 0 00000 imm2(2) Rm(4) ]", mnemonic="LDRB") -@ispec("32[ 11111 00 0 0 01 1 Rn(4) Rt(4) 0 00000 imm2(2) Rm(4) ]", mnemonic="LDRH") -@ispec("32[ 11111 00 1 0 00 1 Rn(4) Rt(4) 0 00000 imm2(2) Rm(4) ]", mnemonic="LDRSB") -@ispec("32[ 11111 00 1 0 01 1 Rn(4) Rt(4) 0 00000 imm2(2) Rm(4) ]", mnemonic="LDRSH") -@ispec("32[ 11111 00 0 0 10 0 Rn(4) Rt(4) 0 00000 imm2(2) Rm(4) ]", mnemonic="STR") -@ispec("32[ 11111 00 0 0 00 0 Rn(4) Rt(4) 0 00000 imm2(2) Rm(4) ]", mnemonic="STRB") -@ispec("32[ 11111 00 0 0 01 0 Rn(4) Rt(4) 0 00000 imm2(2) Rm(4) ]", mnemonic="STRH") -def T2_LDR_r(obj,Rn,Rt,imm2,Rm): +@ispec("32[ Rt(4) 0 00000 imm2(2) Rm(4) 11111 00 0 0 10 1 Rn(4) ]", mnemonic="LDR") +@ispec("32[ Rt(4) 0 00000 imm2(2) Rm(4) 11111 00 0 0 00 1 Rn(4) ]", mnemonic="LDRB") +@ispec("32[ Rt(4) 0 00000 imm2(2) Rm(4) 11111 00 0 0 01 1 Rn(4) ]", mnemonic="LDRH") +@ispec("32[ Rt(4) 0 00000 imm2(2) Rm(4) 11111 00 1 0 00 1 Rn(4) ]", mnemonic="LDRSB") +@ispec("32[ Rt(4) 0 00000 imm2(2) Rm(4) 11111 00 1 0 01 1 Rn(4) ]", mnemonic="LDRSH") +@ispec("32[ Rt(4) 0 00000 imm2(2) Rm(4) 11111 00 0 0 10 0 Rn(4) ]", mnemonic="STR") +@ispec("32[ Rt(4) 0 00000 imm2(2) Rm(4) 11111 00 0 0 00 0 Rn(4) ]", mnemonic="STRB") +@ispec("32[ Rt(4) 0 00000 imm2(2) Rm(4) 11111 00 0 0 01 0 Rn(4) ]", mnemonic="STRH") +def A_deref(obj,Rn,Rt,imm2,Rm): obj.n = env.regs[Rn] obj.t = env.regs[Rt] obj.m = env.regs[Rm]<>8) + return _ror2(v,x>>8) + +def ARMExpandImm_C(x): + v = ARMExpandImm(x) + return (v,v.bit(31)) def ThumbExpandImm(imm12): x = int(imm12,2) @@ -102,19 +106,30 @@ def ThumbExpandImm(imm12): return cst(imm32,32) else: v = cst(1<<7 + x&0x7f,32) - return ror(v,(x>>7)&0x1f) + return _ror(v,(x>>7)&0x1f) + +def ITAdvance(itstate): + if itstate&7 == 0: + return 0 + else: + it_hi = itstate & 0b11100000 + it_lo = itstate & 0xf + return it_hi | (it_lo<<1) def InITBlock(itstate): - return itstate != 0 + return itstate&0xf != 0 def LastInITBlock(itstate): - return itstate == 0b1000 + return itstate&0xf == 0b1000 -def ror(x,n): +def _ror(x,n): xx = x&0xffffffff return (xx>>n | xx<<(32-n))&0xffffffff -def ror2(x,n): + +def _ror2(x,n): xx = x&0xffffffff nn = n+n return (xx>>nn | xx<<(32-nn))&0xffffffff +def BadReg(r): + return (r==13 or r==15) diff --git a/amoco/arch/x86/spec_fpu.py b/amoco/arch/x86/spec_fpu.py index f61549b..d6a5964 100644 --- a/amoco/arch/x86/spec_fpu.py +++ b/amoco/arch/x86/spec_fpu.py @@ -18,3 +18,187 @@ def ia32_nooperand(obj): pass +# D9 C0+i +@ispec_ia32("16>[ {D9} reg(3) 0 0011 ]", mnemonic = "FLD") +# DD D0+i +@ispec_ia32("16>[ {DD} reg(3) 0 1011 ]", mnemonic = "FST") +# DD D8+i +@ispec_ia32("16>[ {DD} reg(3) 1 1011 ]", mnemonic = "FSTP") +# D9 C8+i +@ispec_ia32("16>[ {D9} reg(3) 1 0011 ]", mnemonic = "FXCH") +@ispec_ia32("16>[ {D8} reg(3) 0 1011 ]", mnemonic = "FCOM") # D8 D0+i +@ispec_ia32("16>[ {D8} reg(3) 1 1011 ]", mnemonic = "FCOMP") # D8 D8+i +@ispec_ia32("16>[ {DD} reg(3) 0 0111 ]", mnemonic = "FUCOM") # DD E0+i +@ispec_ia32("16>[ {DD} reg(3) 1 0111 ]", mnemonic = "FUCOMP") # DD E8+i +@ispec_ia32("16>[ {DD} reg(3) 0 0011 ]", mnemonic = "FFREE") # DD C0+i +def ia32_fpu_reg(obj, reg): + obj.operands = [env.st(reg)] + obj.type = type_data_processing + + +@ispec_ia32("*>[ {D9} /0 ]", mnemonic = "FLD", _size = 32) +@ispec_ia32("*>[ {DD} /0 ]", mnemonic = "FLD", _size = 64) +@ispec_ia32("*>[ {DB} /5 ]", mnemonic = "FLD", _size = 80) +@ispec_ia32("*>[ {DF} /0 ]", mnemonic = "FILD", _size = 16) +@ispec_ia32("*>[ {DB} /0 ]", mnemonic = "FILD", _size = 32) +@ispec_ia32("*>[ {DF} /5 ]", mnemonic = "FILD", _size = 64) +@ispec_ia32("*>[ {D9} /2 ]", mnemonic = "FST", _size = 32) +@ispec_ia32("*>[ {DD} /2 ]", mnemonic = "FST", _size = 64) +@ispec_ia32("*>[ {D9} /3 ]", mnemonic = "FSTP", _size = 32) +@ispec_ia32("*>[ {DD} /3 ]", mnemonic = "FSTP", _size = 64) +@ispec_ia32("*>[ {DB} /7 ]", mnemonic = "FSTP", _size = 80) +@ispec_ia32("*>[ {DF} /2 ]", mnemonic = "FIST", _size = 16) +@ispec_ia32("*>[ {DB} /2 ]", mnemonic = "FIST", _size = 32) +@ispec_ia32("*>[ {DF} /3 ]", mnemonic = "FISTP", _size = 16) +@ispec_ia32("*>[ {DB} /3 ]", mnemonic = "FISTP", _size = 32) +@ispec_ia32("*>[ {DF} /7 ]", mnemonic = "FISTP", _size = 64) +@ispec_ia32("*>[ {DF} /1 ]", mnemonic = "FISTPP", _size = 16) +@ispec_ia32("*>[ {DB} /1 ]", mnemonic = "FISTPP", _size = 32) +@ispec_ia32("*>[ {DD} /1 ]", mnemonic = "FISTPP", _size = 64) +@ispec_ia32("*>[ {D8} /2 ]", mnemonic = "FCOM", _size = 32) +@ispec_ia32("*>[ {DC} /2 ]", mnemonic = "FCOM", _size = 64) +@ispec_ia32("*>[ {D8} /3 ]", mnemonic = "FCOMP", _size = 32) +@ispec_ia32("*>[ {DC} /3 ]", mnemonic = "FCOMP", _size = 64) +@ispec_ia32("*>[ {D8} /4 ]", mnemonic = "FSUB", _size = 32) +@ispec_ia32("*>[ {DC} /4 ]", mnemonic = "FSUB", _size = 64) +@ispec_ia32("*>[ {DA} /4 ]", mnemonic = "FISUB", _size = 32) +@ispec_ia32("*>[ {DE} /4 ]", mnemonic = "FISUB", _size = 16) +@ispec_ia32("*>[ {D8} /5 ]", mnemonic = "FSUBR", _size = 32) +@ispec_ia32("*>[ {DC} /5 ]", mnemonic = "FSUBR", _size = 64) +@ispec_ia32("*>[ {DA} /5 ]", mnemonic = "FISUBR", _size = 32) +@ispec_ia32("*>[ {DE} /5 ]", mnemonic = "FISUBR", _size = 16) +@ispec_ia32("*>[ {D8} /0 ]", mnemonic = "FADD", _size = 32) +@ispec_ia32("*>[ {DC} /0 ]", mnemonic = "FADD", _size = 64) +@ispec_ia32("*>[ {DA} /0 ]", mnemonic = "FIADD", _size = 32) +@ispec_ia32("*>[ {DE} /0 ]", mnemonic = "FIADD", _size = 16) +@ispec_ia32("*>[ {D8} /6 ]", mnemonic = "FDIV", _size = 32) +@ispec_ia32("*>[ {DC} /6 ]", mnemonic = "FDIV", _size = 64) +@ispec_ia32("*>[ {DA} /6 ]", mnemonic = "FIDIV", _size = 32) +@ispec_ia32("*>[ {DE} /6 ]", mnemonic = "FIDIV", _size = 16) +@ispec_ia32("*>[ {D8} /7 ]", mnemonic = "FDIVR", _size = 32) +@ispec_ia32("*>[ {DC} /7 ]", mnemonic = "FDIVR", _size = 64) +@ispec_ia32("*>[ {DA} /7 ]", mnemonic = "FIDIVR", _size = 32) +@ispec_ia32("*>[ {DE} /7 ]", mnemonic = "FIDIVR", _size = 16) +@ispec_ia32("*>[ {D8} /1 ]", mnemonic = "FMUL", _size = 32) +@ispec_ia32("*>[ {DC} /1 ]", mnemonic = "FMUL", _size = 64) +@ispec_ia32("*>[ {DA} /1 ]", mnemonic = "FIMUL", _size = 32) +@ispec_ia32("*>[ {DE} /1 ]", mnemonic = "FIMUL", _size = 16) +@ispec_ia32("*>[ {DF} /4 ]", mnemonic = "FBLD", _size = 80) +@ispec_ia32("*>[ {DF} /6 ]", mnemonic = "FBSTP", _size = 80) +@ispec_ia32("*>[ {DE} /2 ]", mnemonic = "FICOM", _size = 16) +@ispec_ia32("*>[ {DA} /2 ]", mnemonic = "FICOM", _size = 32) +@ispec_ia32("*>[ {DE} /3 ]", mnemonic = "FICOMP", _size = 16) +@ispec_ia32("*>[ {DA} /3 ]", mnemonic = "FICOMP", _size = 32) +@ispec_ia32("*>[ {D9} /5 ]", mnemonic = "FLDCW", _size = 16) +@ispec_ia32("*>[ {9B}{D9} /7 ]", mnemonic = "FSTCW", _size = 16) +@ispec_ia32("*>[ {D9} /7 ]", mnemonic = "FNSTCW", _size = 16) +@ispec_ia32("*>[ {9B}{D9} /6 ]", mnemonic = "FSTENV", _size = 28*8) +@ispec_ia32("*>[ {D9} /6 ]", mnemonic = "FNSTENV", _size = 28*8) +@ispec_ia32("*>[ {D9} /4 ]", mnemonic = "FLDENV", _size = 28*8) #TODO : 16 bits size +@ispec_ia32("*>[ {DD} /4 ]", mnemonic = "FRSTOR", _size = 108*8) #TODO : 16 bits size +@ispec_ia32("*>[ {9B}{DD} /6 ]", mnemonic = "FSAVE", _size = 108*8) #TODO : 16 bits size +@ispec_ia32("*>[ {DD} /6 ]", mnemonic = "FNSAVE", _size = 108*8) #TODO : 16 bits size +@ispec_ia32("*>[ {0F}{AE} /0 ]", mnemonic = "FXSAVE", _size = 512*8) +@ispec_ia32("*>[ {0F}{AE} /1 ]", mnemonic = "FXRSTOR", _size = 512*8) +def ia32_fpu_mem(obj, Mod, RM, data, _size): + # registers are not allowed + if Mod == 3: + raise InstructionError(obj) + op1, data = getModRM(obj,Mod,RM,data) + op1.size = _size + obj.operands = [op1] + obj.type = type_data_processing + +@ispec_ia32("24>[ {9B}{DF}{E0} ]", mnemonic = "FSTSW") +@ispec_ia32("16>[ {DF}{E0} ]", mnemonic = "FNSTSW") +def ia32_fstsw_ax(obj): + obj.operands = [ env.getreg(0, 16) ] + obj.type = type_data_processing + +@ispec_ia32("*>[ {DD} /7 ]", mnemonic = "FNSTSW") +@ispec_ia32("*>[ {9B}{DD} /7 ]", mnemonic = "FSTSW") +def ia32_fstsw(obj, Mod, RM, data): + op1,data = getModRM(obj,Mod,RM,data) + obj.operands = [op1] + obj.type = type_data_processing + +@ispec_ia32("16>[ {D9}{E0} ]", mnemonic = "FCHS") +@ispec_ia32("16>[ {D9}{E8} ]", mnemonic = "FLD1") +@ispec_ia32("16>[ {D9}{E9} ]", mnemonic = "FLDL2T") +@ispec_ia32("16>[ {D9}{EA} ]", mnemonic = "FLDL2E") +@ispec_ia32("16>[ {D9}{EB} ]", mnemonic = "FLDPI") +@ispec_ia32("16>[ {D9}{EC} ]", mnemonic = "FLDLG2") +@ispec_ia32("16>[ {D9}{ED} ]", mnemonic = "FLDLN2") +@ispec_ia32("16>[ {D9}{EE} ]", mnemonic = "FLDZ") +@ispec_ia32("16>[ {DE}{D9} ]", mnemonic = "FCOMPP") +@ispec_ia32("16>[ {DA}{E9} ]", mnemonic = "FUCOMPP") +@ispec_ia32("16>[ {D9}{F0} ]", mnemonic = "F2XM1") +@ispec_ia32("16>[ {D9}{E1} ]", mnemonic = "FABS") +@ispec_ia32("16>[ {DB}{E2} ]", mnemonic = "FNCLEX") +@ispec_ia32("24>[ {9B}{DB}{E2} ]", mnemonic = "FCLEX") +@ispec_ia32("16>[ {DB}{E3} ]", mnemonic = "FNINIT") +@ispec_ia32("24>[ {9B}{DB}{E3} ]", mnemonic = "FINIT") +@ispec_ia32("16>[ {D9}{E4} ]", mnemonic = "FTST") +@ispec_ia32("16>[ {D9}{E5} ]", mnemonic = "FXAM") +@ispec_ia32("16>[ {D9}{F1} ]", mnemonic = "FYL2X") +@ispec_ia32("16>[ {D9}{F2} ]", mnemonic = "FPTAN") +@ispec_ia32("16>[ {D9}{F3} ]", mnemonic = "FPATAN") +@ispec_ia32("16>[ {D9}{FA} ]", mnemonic = "FSQRT") +@ispec_ia32("16>[ {D9}{FB} ]", mnemonic = "FSINCOS") +@ispec_ia32("16>[ {D9}{FE} ]", mnemonic = "FSIN") +@ispec_ia32("16>[ {D9}{FF} ]", mnemonic = "FCOS") +@ispec_ia32("16>[ {D9}{F8} ]", mnemonic = "FPREM") +@ispec_ia32("16>[ {D9}{F9} ]", mnemonic = "FYL2XP1") +@ispec_ia32("16>[ {D9}{F4} ]", mnemonic = "FXTRACT") +@ispec_ia32("16>[ {D9}{F5} ]", mnemonic = "FPREM1") +@ispec_ia32("16>[ {D9}{F6} ]", mnemonic = "FDECSTP") +@ispec_ia32("16>[ {D9}{F7} ]", mnemonic = "FINCSTP") +@ispec_ia32("16>[ {D9}{FC} ]", mnemonic = "FRNDINT") +@ispec_ia32("16>[ {D9}{FD} ]", mnemonic = "FSCALE") +@ispec_ia32("16>[ {D9}{D0} ]", mnemonic = "FNOP") +def fld_fpu_noop(obj): + obj.type = type_data_processing + +@ispec_ia32("16>[ {D8} reg(3) 0 0111 ]", mnemonic = "FSUB", _src=None, _dest=0) # D8 E0+i +@ispec_ia32("16>[ {DC} reg(3) 1 0111 ]", mnemonic = "FSUB", _src=0, _dest=None) # DC E8+i +@ispec_ia32("16>[ {DE} reg(3) 1 0111 ]", mnemonic = "FSUBP", _src=0, _dest=None) # DE E8+i +@ispec_ia32("16>[ {D8} reg(3) 1 0111 ]", mnemonic = "FSUBR", _src=None, _dest=0) # D8 E8+i +@ispec_ia32("16>[ {DC} reg(3) 0 0111 ]", mnemonic = "FSUBR", _src=0, _dest=None) # DC E0+i +@ispec_ia32("16>[ {DE} reg(3) 0 0111 ]", mnemonic = "FSUBRP", _src=0, _dest=None) # DE E0+i +@ispec_ia32("16>[ {D8} reg(3) 0 0011 ]", mnemonic = "FADD", _src=None, _dest=0) # D8 C0+i +@ispec_ia32("16>[ {DC} reg(3) 0 0011 ]", mnemonic = "FADD", _src=0, _dest=None) # DC C0+i +@ispec_ia32("16>[ {DE} reg(3) 0 0011 ]", mnemonic = "FADDP", _src=0, _dest=None) # DE C0+i +@ispec_ia32("16>[ {D8} reg(3) 0 1111 ]", mnemonic = "FDIV", _src=None, _dest=0) # D8 F0+i +@ispec_ia32("16>[ {DC} reg(3) 1 1111 ]", mnemonic = "FDIV", _src=0, _dest=None) # DC F8+i +@ispec_ia32("16>[ {DE} reg(3) 1 1111 ]", mnemonic = "FDIVP", _src=0, _dest=None) # DE F8+i +@ispec_ia32("16>[ {D8} reg(3) 1 1111 ]", mnemonic = "FDIVR", _src=None, _dest=0) # D8 F8+i +@ispec_ia32("16>[ {DC} reg(3) 0 1111 ]", mnemonic = "FDIVR", _src=0, _dest=None) # DC F0+i +@ispec_ia32("16>[ {DE} reg(3) 0 1111 ]", mnemonic = "FDIVRP", _src=0, _dest=None) # DE F0+i +@ispec_ia32("16>[ {D8} reg(3) 1 0011 ]", mnemonic = "FMUL", _src=None, _dest=0) # D8 C8+i +@ispec_ia32("16>[ {DC} reg(3) 1 0011 ]", mnemonic = "FMUL", _src=0, _dest=None) # DC C8+i +@ispec_ia32("16>[ {DE} reg(3) 1 0011 ]", mnemonic = "FMULP", _src=0, _dest=None) # DE C8+i +@ispec_ia32("16>[ {DA} reg(3) 0 0011 ]", mnemonic = "FCMOVB", _src=None, _dest=0) # DA C0+i +@ispec_ia32("16>[ {DA} reg(3) 1 0011 ]", mnemonic = "FCMOVE", _src=None, _dest=0) # DA C8+i +@ispec_ia32("16>[ {DA} reg(3) 0 1011 ]", mnemonic = "FCMOVBE", _src=None, _dest=0) # DA D0+i +@ispec_ia32("16>[ {DA} reg(3) 1 1011 ]", mnemonic = "FCMOVU", _src=None, _dest=0) # DA D8+i +@ispec_ia32("16>[ {DB} reg(3) 0 0011 ]", mnemonic = "FCMOVNB", _src=None, _dest=0) # DB C0+i +@ispec_ia32("16>[ {DB} reg(3) 1 0011 ]", mnemonic = "FCMOVNE", _src=None, _dest=0) # DB C8+i +@ispec_ia32("16>[ {DB} reg(3) 0 1011 ]", mnemonic = "FCMOVNBE", _src=None, _dest=0) # DB D0+i +@ispec_ia32("16>[ {DB} reg(3) 1 1011 ]", mnemonic = "FCMOVNU", _src=None, _dest=0) # DB D8+i +@ispec_ia32("16>[ {DB} reg(3) 0 1111 ]", mnemonic = "FCOMI", _src=None, _dest=0) # DB F0+i +@ispec_ia32("16>[ {DF} reg(3) 0 1111 ]", mnemonic = "FCOMIP", _src=None, _dest=0) # DF F0+i +@ispec_ia32("16>[ {DB} reg(3) 1 0111 ]", mnemonic = "FUCOMI", _src=None, _dest=0) # DB E8+i +@ispec_ia32("16>[ {DF} reg(3) 1 0111 ]", mnemonic = "FUCOMIP", _src=None, _dest=0) # DF E8+i +def ia32_fpu_st(obj, reg, _dest, _src): + # FSUBP + if _dest is None and _src is None: + return + if _dest is None: + _dest = reg + elif _src is None: + _src = reg + op1 = env.st(_dest) + op2 = env.st(_src) + obj.operands = [op1, op2] + obj.type = type_data_processing + diff --git a/amoco/cas/expressions.py b/amoco/cas/expressions.py index 325d8e5..6b6047f 100644 --- a/amoco/cas/expressions.py +++ b/amoco/cas/expressions.py @@ -155,6 +155,8 @@ def __pow__(self,n): return oper('**',self,n) @_checkarg_numeric def __div__(self,n): return oper('/',self,n) @_checkarg_numeric + def __mod__(self,n): return oper('%',self,n) + @_checkarg_numeric def __floordiv__(self,n): return oper('//',self,n) @_checkarg_numeric def __and__(self,n): return oper('&',self,n) @@ -311,6 +313,10 @@ def __div__(self,n): if n._is_cst: return cst(int(float(self.value)/n.value),self.size) else : return exp.__div__(self,n) @_checkarg_numeric + def __mod__(self,n): + if n._is_cst: return cst(self.value%n.value,self.size) + else : return exp.__mod__(self,n) + @_checkarg_numeric @_checkarg_sizes def __and__(self,n): if n._is_cst: return cst(self.v&n.v,self.size) @@ -413,7 +419,7 @@ def __str__(self): # reg holds 32-bit register reference (refname). #------------------------------------------------------------------------------ class reg(exp): - __slots__ = ['ref'] + __slots__ = ['ref','_subrefs'] _is_def = True _is_reg = True @@ -421,6 +427,7 @@ def __init__(self,refname,size=32): self.size = size self.sf = False self.ref = refname + self._subrefs = {} @_checkarg_slice def __getitem__(self,i): @@ -722,12 +729,23 @@ def __init__(self,x,pos,size,ref=None): self.size = size self.sf = False self.pos = pos - self.ref = ref + self.setref(ref) + + def setref(self,ref): + if self.x._is_reg: + if ref is None: + ref = self.x._subrefs.get((self.pos,self.size),None) + else: + self.x._subrefs[(self.pos,self.size)] = ref + self.ref = ref + + def raw(self): + return "%s[%d:%d]"%(str(self.x),self.pos,self.pos+self.size) def __str__(self): - return self.ref or "%s[%d:%d]"%(str(self.x),self.pos,self.pos+self.size) + return self.ref or self.raw() ## - def __hash__(self): return hash("%s[%d:%d]"%(str(self.x),self.pos,self.pos+self.size)) + def __hash__(self): return hash(self.raw()) def eval(self,env): n = self.x.eval(env) @@ -833,7 +851,7 @@ def __init__(self,op,l,r=None): self.sf = l.sf if self.l._is_eqn: self.prop |= self.l.prop if self.r is not None: - self.sf |= r.sf + if self.prop==1: self.sf |= r.sf if self.r._is_eqn : self.prop |= self.r.prop @classmethod @@ -877,16 +895,17 @@ def depth(self): import operator def ror(x,n): - return (x>>n | x<<(x.size-n)) + return (x>>n | x<<(x.size-n)) if x._is_cst else op('>>>',x,n) def rol(x,n): - return (x<>(x.size-n)) + return (x<>(x.size-n)) if x._is_cst else op('<<<',x,n) OP_ARITH = {'+' : operator.add, '-' : operator.sub, '*' : operator.mul, '**' : operator.pow, '/' : operator.div, + '%' : operator.mod, } OP_LOGIC = {'&' : operator.and_, '|' : operator.or_, diff --git a/amoco/cas/mapper.py b/amoco/cas/mapper.py index 5d12caa..82d4d44 100644 --- a/amoco/cas/mapper.py +++ b/amoco/cas/mapper.py @@ -82,7 +82,7 @@ def __setitem__(self,k,v): try: loc = k.addr(self) except TypeError: - logger.verbose('setitem ignored (invalid left-value expression)') + logger.error('setitem ignored (invalid left-value expression)') return if k._is_slc and not loc._is_reg: raise ValueError('memory location slc is not supported') diff --git a/amoco/main.py b/amoco/main.py index 07c5fd0..ca01539 100644 --- a/amoco/main.py +++ b/amoco/main.py @@ -97,7 +97,6 @@ def getcfg(self,loc=None): order = -1 if self.policy['depth-first'] else 0 lazy = self.policy['branch-lazy'] F = cfg.func() - pc = self.prog.PC() while len(spool)>0: current,parent = spool.pop(order) for b in self.iterblocks(loc=current):