Mercurial > lcfOS
diff python/ppci/target/arm/instructions.py @ 346:3bb7dcfe5529
expanded arm target
author | Windel Bouwman |
---|---|
date | Fri, 07 Mar 2014 17:05:32 +0100 |
parents | b4882ff0ed06 |
children | 2b02bd286fe9 |
line wrap: on
line diff
--- a/python/ppci/target/arm/instructions.py Sun Mar 02 17:12:08 2014 +0100 +++ b/python/ppci/target/arm/instructions.py Fri Mar 07 17:05:32 2014 +0100 @@ -1,31 +1,10 @@ - from ..basetarget import Instruction +from ...bitfun import rotate_left from .token import ArmToken from .registers import R0, SP, ArmRegister -# Helpers: - -def rotate_right(v, n): - """ bit-wise Rotate right n times """ - mask = (2**n) - 1 - mask_bits = v & mask - return (v >> n) | (mask_bits << (32 - n)) - -def rotate_left(v, n): - assert n >= 0 - assert n < 32 - return rotate_right(v, 32 - n) - -masks = [rotate_right(0xFF, i * 2) for i in range(16)] -#0x000000FF, -#0xC000007F, -#0xF000000F, -#0xFC000003, -#0xFF000000, # 4 - -assert masks[4] == 0xFF000000, hex(masks[4]) def encode_imm32(v): """ Bundle 32 bit value into 4 bits rotation and 8 bits value @@ -46,20 +25,40 @@ self.token = ArmToken() -class Mov(ArmInstruction): +class Dcd(ArmInstruction): + def __init__(self, v): + super().__init__() + self.v = v + + def encode(self): + self.token[0:32] = self.v + return self.token.encode() + + +def Mov(*args): + if len(args) == 2: + if isinstance(args[1], int): + return Mov1(*args) + elif isinstance(args[1], ArmRegister): + return Mov2(*args) + raise Exception() + + +class Mov1(ArmInstruction): """ Mov Rd, imm16 """ def __init__(self, reg, imm): super().__init__() + assert type(imm) is int self.reg = reg self.imm = imm def encode(self): - self.token[0:12] = self.imm + self.token[0:12] = encode_imm32(self.imm) self.token.Rd = self.reg.num self.token[16:20] = 0 - self.token[20] = 0 + self.token[20] = 0 # Set flags self.token[21:28] = 0b0011101 - self.token.cond = 0xE # Always! + self.token.cond = AL return self.token.encode() def relocations(self): @@ -69,6 +68,23 @@ return 'Mov {}, {}'.format(self.reg, self.imm) +class Mov2(ArmInstruction): + def __init__(self, rd, rm): + super().__init__() + self.rd = rd + self.rm = rm + + def encode(self): + self.token[0:4] = self.rm.num + self.token[4:12] = 0 + self.token[12:16] = self.rd.num + self.token[16:20] = 0 + self.token.S = 0 + self.token[21:28] = 0xD + self.token.cond = AL + return self.token.encode() + + def Add(*args): if len(args) == 3 and isinstance(args[0], ArmRegister) and \ isinstance(args[1], ArmRegister): @@ -87,6 +103,27 @@ return Sub2(args[0], args[1], args[2]) raise Exception() +def Mul(*args): + return Mul1(args[0], args[1], args[2]) + + +class Mul(ArmInstruction): + def __init__(self, rd, rn, rm): + super().__init__() + self.rd = rd + self.rn = rn + self.rm = rm + + def encode(self): + self.token[0:4] = self.rn.num + self.token[4:8] = 0b1001 + self.token[8:12] = self.rm.num + self.token[16:20] = self.rd.num + self.token.S = 0 + self.token.cond = AL + return self.token.encode() + + class OpRegRegReg(ArmInstruction): """ add rd, rn, rm """ def __init__(self, rd, rn, rm, shift=0): @@ -170,6 +207,8 @@ return [(self.target, 'b_imm24')] +EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL = range(15) + class BranchBase(BranchBaseRoot): opcode = 0b1010 @@ -177,18 +216,108 @@ opcode = 0b1011 class Bl(BranchLinkBase): - cond = 0xE + cond = AL class B(BranchBase): - cond = 0xE + cond = AL class Beq(BranchBase): - cond = 0x0 + cond = EQ class Bgt(BranchBase): - cond = 0xC + cond = GT class Ble(BranchBase): - cond = 0xD + cond = LE + +class Blt(BranchBase): + cond = LT + + +# Memory: + +def reg_list_to_mask(reg_list): + mask = 0 + for reg in reg_list: + mask |= (1 << reg.num) + return mask + + +class Push(ArmInstruction): + def __init__(self, register_set): + super().__init__() + self.reg_list = register_set + + def encode(self): + self.token.cond = AL + self.token[16:28] = 0b100100101101 + reg_list = 0 + self.token[0:16] = reg_list_to_mask(self.reg_list) + return self.token.encode() + +class Pop(ArmInstruction): + def __init__(self, register_set): + super().__init__() + self.reg_list = register_set + + def encode(self): + self.token.cond = AL + self.token[16:28] = 0b100010111101 + self.token[0:16] = reg_list_to_mask(self.reg_list) + return self.token.encode() +def Ldr(*args): + if len(args) == 3 and isinstance(args[1], ArmRegister): + return Ldr1(*args) + elif len(args) == 2 and isinstance(args[1], ArmRegister): + return Ldr1(args[0], args[1], 0) + raise Exception() + +def Str(*args): + if len(args) == 3 and isinstance(args[1], ArmRegister): + return Str1(*args) + elif len(args) == 2 and isinstance(args[1], ArmRegister): + return Str1(args[0], args[1], 0) + raise Exception() + + +class LdrStrBase(ArmInstruction): + def __init__(self, rt, rn, offset): + super().__init__() + self.rt = rt + self.rn = rn + self.offset = offset + + def encode(self): + self.token.cond = AL + self.token.Rn = self.rn.num + self.token[25:28] = self.opcode + self.token[20] = self.bit20 + self.token[12:16] = self.rt.num + self.token[24] = 1 # Index + if self.offset >= 0: + self.token[23] = 1 # U == 1 'add' + self.token[0:12] = self.offset + else: + self.token[23] = 0 + self.token[0:12] = -self.offset + return self.token.encode() + + +class Str1(LdrStrBase): + opcode = 0b010 + bit20 = 0 + + +class Ldr1(LdrStrBase): + opcode = 0b010 + bit20 = 1 + + +class Ldr3(ArmInstruction): + """ Load PC relative constant value """ + def __init__(self, rt, label): + self.rt = rt + self.label = label +