hipe_arm_encode.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 978 行 · 第 1/3 页
ERL
978 行
%%% -*- erlang-indent-level: 2 -*-%%% $Id$%%% Encode symbolic ARM instructions to binary form.%%% Copyright (C) 2005 Mikael Pettersson%%%%%% Implementation Notes:%%% - The Thumb instruction set is a different entity, and is%%% not and never will be supported by this module.%%% - Instructions and instruction forms that are unpredictable%%% or useless in User mode are not supported. They include:%%% + Data Processing Instructions with S=1 and Rd=15.%%% + The LDM(2), LDM(3), and STM(2) instructions.%%% + MRS instructions that access the SPSR.%%% + MSR instructions that access the SPSR.%%% + The LDBRT, LDRT, STBRT, and STRT instructions.%%%%%% Instruction Operands:%%%%%% S ::= {s,0} | {s,1}%%% L ::= {l,0} | {l,1}%%% R ::= {r,RNum}%%% CR ::= {cr,CRNum}%%%%%% Cond ::= {cond,CondName}%%% CondName ::= eq | ne | cs | hs | cc | lo | mi | pl | vs%%% | vc | hi | ls | ge | lt | gt | ge | al%%%%%% Imm<N> ::= {imm<N>,<N bits>} for N in 4, 5, 8, 12, 16, 24, and 25%%%%%% Am1ShifterOperand%%% ::= {Imm8,Imm4}%%% | Rm%%% | {Rm,Am1ShiftOp}%%% Am1ShiftOp ::= {ShiftOp,Imm5}%%% | {ShiftOp,Rs}%%% | rrx%%% ShiftOp ::= lsl | lsr | asr | ror%%%%%% Am2LSWUBOperand ::= {immediate_offset,Rn,Sign,Imm12}%%% | {register_offset,Rn,Sign,Rm} // redundant%%% | {scaled_register_offset,Rn,Sign,Rm,Am2ShiftOp}%%% | {immediate_pre_indexed,Rn,Sign,Imm12}%%% | {register_pre_indexed,Rn,Sign,Rm} // redundant%%% | {scaled_register_pre_indexed,Rn,Sign,Rm,Am2ShiftOp}%%% | {immediate_post_indexed,Rn,Sign,Imm12}%%% | {register_post_indexed,Rn,Sign,Rm} // redundant%%% | {scaled_register_post_indexed,Rn,Sign,Rm,Am2ShiftOp}%%% Am2ShiftOp ::= {ShiftOp,Imm5}%%% | rrx%%% Sign ::= + | -%%%%%% Am3MiscLSOperand::= {immediate_offset,Rn,Sign,Imm8}%%% | {register_offset,Rn,Sign,Rm}%%% | {immediate_pre_indexed,Rn,Sign,Imm8}%%% | {register_pre_indexed,Rn,Sign,Rm}%%% | {immediate_post_indexed,Rn,Sign,Imm8}%%% | {register_post_indexed,Rn,Sign,Rm}%%%%%% Am4LSMultiple ::= ia | ib | da | db%%% | fd | ed | fa | ea%%%%%% Am5LSCoprocessor::= {offset,Rn,Sign,Imm8}%%% | {pre_indexed,Rn,Sign,Imm8}%%% | {post_indexed,Rn,Sign,Imm8}%%% | {unindexed,Rn,Imm8}-module(hipe_arm_encode).-export([insn_encode/2]).%%-define(TESTING,1).-ifdef(TESTING).-export([dotest/0, dotest/1]).-endif.-define(ASSERT(G), if G -> []; true -> exit({assertion_failed,?MODULE,?LINE,??G}) end).bf(LeftBit, RightBit, Value) -> ?ASSERT(32 > LeftBit), ?ASSERT(LeftBit >= RightBit), ?ASSERT(RightBit >= 0), ?ASSERT(Value >= 0), ?ASSERT(Value < (1 bsl ((LeftBit - RightBit) + 1))), Value bsl RightBit.-define(BF(LB,RB,V), bf(LB,RB,V)).-define(BIT(Pos,Val), ?BF(Pos,Pos,Val)).-define(BITS(N,Val), ?BF(N,0,Val)).%%%%%% Addressing Modes%%%am1_shifter_operand(Rn, Rd, ShifterOperand) -> case ShifterOperand of {{imm8,Imm8},{imm4,RotImm4}} -> ?BIT(25,1) bor ?BF(11,8,RotImm4) bor ?BF(7,0,Imm8); {r,Rm} -> %% same as Rm LSL #0 ?BF(3,0,Rm); {{r,Rm},ShiftOp} -> am1_shift_op(Rn, Rd, Rm, ShiftOp) bor ?BF(3,0,Rm) end.am1_shift_op(_Rn, _Rd, _Rm, {ShiftOp,{imm5,ShiftImm5}}) -> case ShiftOp of 'ror' -> ?ASSERT(ShiftImm5 =/= 0); % denotes RRX form _ -> [] end, ?BF(11,7,ShiftImm5) bor shift_op_bits65(ShiftOp);am1_shift_op(Rn, Rd, Rm, {ShiftOp,{r,Rs}}) -> ?ASSERT(Rn =/= 15), % UNPREDICTABLE ?ASSERT(Rd =/= 15), % UNPREDICTABLE ?ASSERT(Rm =/= 15), % UNPREDICTABLE ?ASSERT(Rs =/= 15), % UNPREDICTABLE ?BF(11,8,Rs) bor shift_op_bits65(ShiftOp) bor ?BIT(4,1);am1_shift_op(_Rn, _Rd, _Rm, 'rrx') -> ?BF(6,5,2#11).shift_op_bits65(ShiftOp) -> case ShiftOp of 'lsl' -> ?BF(6,5,2#00); 'lsr' -> ?BF(6,5,2#01); 'asr' -> ?BF(6,5,2#10); 'ror' -> ?BF(6,5,2#11) end.sign('+') -> ?BIT(23,1);sign('-') -> 0.am2_lswub(Rd, AddressingMode) -> case AddressingMode of {immediate_offset,{r,Rn},Sign,{imm12,Imm12}} -> ?BIT(24,1) bor sign(Sign) bor ?BF(19,16,Rn) bor ?BF(11,0,Imm12); {register_offset,{r,Rn},Sign,{r,Rm}} -> %% same as scaled_register_offset LSL #0 ?ASSERT(Rm =/= 15), % UNPREDICTABLE ?BIT(25,1) bor ?BIT(24,1) bor sign(Sign) bor ?BF(19,16,Rn) bor ?BF(3,0,Rm); {scaled_register_offset,{r,Rn},Sign,{r,Rm},ShiftOp} -> ?ASSERT(Rm =/= 15), % UNPREDICTABLE ?BIT(25,1) bor ?BIT(24,1) bor sign(Sign) bor ?BF(19,16,Rn) bor am2_shift_op(ShiftOp) bor ?BF(3,0,Rm); {immediate_pre_indexed,{r,Rn},Sign,{imm12,Imm12}} -> ?ASSERT(Rd =/= Rn), % UNPREDICTABLE ?ASSERT(Rn =/= 15), % UNPREDICTABLE ?BIT(24,1) bor sign(Sign) bor ?BIT(21,1) bor ?BF(19,16,Rn) bor ?BF(11,0,Imm12); {register_pre_indexed,{r,Rn},Sign,{r,Rm}} -> %% same as scaled_register_pre_indexed LSL #0 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE ?ASSERT(Rn =/= 15), % UNPREDICTABLE ?ASSERT(Rm =/= 15), % UNPREDICTABLE ?ASSERT(Rn =/= Rm), % UNPREDICTABLE ?BIT(25,1) bor ?BIT(24,1) bor sign(Sign) bor ?BIT(21,1) bor ?BF(19,16,Rn) bor ?BF(3,0,Rm); {scaled_register_pre_indexed,{r,Rn},Sign,{r,Rm},ShiftOp} -> ?ASSERT(Rd =/= Rn), % UNPREDICTABLE ?ASSERT(Rn =/= 15), % UNPREDICTABLE ?ASSERT(Rm =/= 15), % UNPREDICTABLE ?ASSERT(Rn =/= Rm), % UNPREDICTABLE ?BIT(25,1) bor ?BIT(24,1) bor sign(Sign) bor ?BIT(21,1) bor ?BF(19,16,Rn) bor am2_shift_op(ShiftOp) bor ?BF(3,0,Rm); {immediate_post_indexed,{r,Rn},Sign,{imm12,Imm12}} -> ?ASSERT(Rd =/= Rn), % UNPREDICTABLE ?ASSERT(Rn =/= 15), % UNPREDICTABLE sign(Sign) bor ?BF(19,16,Rn) bor ?BF(11,0,Imm12); {register_post_indexed,{r,Rn},Sign,{r,Rm}} -> %% same as scaled_register_post_indexed LSL #0 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE ?BIT(25,1) bor sign(Sign) bor ?BF(19,6,Rn) bor ?BF(3,0,Rm); {scaled_register_post_indexed,{r,Rn},Sign,{r,Rm},ShiftOp} -> ?ASSERT(Rd =/= Rn), % UNPREDICTABLE ?ASSERT(Rn =/= 15), % UNPREDICTABLE ?ASSERT(Rm =/= 15), % UNPREDICTABLE ?ASSERT(Rn =/= Rm), % UNPREDICTABLE ?BIT(25,1) bor sign(Sign) bor ?BF(19,16,Rn) bor am2_shift_op(ShiftOp) bor ?BF(3,0,Rm) end.am2_shift_op({ShiftOp,{imm5,ShiftImm5}}) -> case ShiftOp of 'ror' -> ?ASSERT(ShiftImm5 =/= 0); % denotes RRX form _ -> [] end, ?BF(11,7,ShiftImm5) bor shift_op_bits65(ShiftOp);am2_shift_op('rrx') -> ?BF(6,5,2#11).am3_miscls(Rd, AddressingMode) -> case AddressingMode of {immediate_offset,{r,Rn},Sign,{imm8,Imm8}} -> ?BIT(24,1) bor sign(Sign) bor ?BF(22,21,2#10) bor ?BF(19,16,Rn) bor ?BF(11,8,Imm8 bsr 4) bor ?BF(3,0,Imm8 band 2#1111); {register_offset,{r,Rn},Sign,{r,Rm}} -> ?ASSERT(Rm =/= 15), % UNPREDICTABLE ?BIT(24,1) bor sign(Sign) bor ?BF(22,21,2#00) bor ?BF(19,16,Rn) bor ?BF(3,0,Rm); {immediate_pre_indexed,{r,Rn},Sign,{imm8,Imm8}} -> ?ASSERT(Rd =/= Rn), % UNPREDICTABLE ?ASSERT(Rn =/= 15), % UNPREDICTABLE ?BIT(24,1) bor sign(Sign) bor ?BF(22,21,2#11) bor ?BF(19,16,Rn) bor ?BF(11,8,Imm8 bsr 4) bor ?BF(3,0,Imm8 band 2#1111); {register_pre_indexed,{r,Rn},Sign,{r,Rm}} -> ?ASSERT(Rd =/= Rn), % UNPREDICTABLE ?ASSERT(Rm =/= 15), % UNPREDICTABLE ?ASSERT(Rn =/= 15), % UNPREDICTABLE ?ASSERT(Rm =/= Rn), % UNPREDICTABLE ?BIT(24,1) bor sign(Sign) bor ?BF(22,21,2#01) bor ?BF(19,16,Rn) bor ?BF(3,0,Rm); {immediate_post_indexed,{r,Rn},Sign,{imm8,Imm8}} -> ?ASSERT(Rd =/= Rn), % UNPREDICTABLE ?ASSERT(Rn =/= 15), % UNPREDICTABLE ?BIT(24,0) bor sign(Sign) bor ?BF(22,21,2#10) bor ?BF(19,16,Rn) bor ?BF(11,8,Imm8 bsr 4) bor ?BF(3,0,Imm8 band 2#1111); {register_post_indexed,{r,Rn},Sign,{r,Rm}} -> ?ASSERT(Rd =/= Rn), % UNPREDICTABLE ?ASSERT(Rm =/= 15), % UNPREDICTABLE ?ASSERT(Rn =/= 15), % UNPREDICTABLE ?ASSERT(Rm =/= Rn), % UNPREDICTABLE ?BIT(24,0) bor sign(Sign) bor ?BF(22,21,2#00) bor ?BF(19,16,Rn) bor ?BF(3,0,Rm) end.am4_ls_multiple(L, AddressingMode) -> case AddressingMode of 'ia' -> ?BF(24,23,2#01); 'ib' -> ?BF(24,23,2#11); 'da' -> ?BF(24,23,2#00); 'db' -> ?BF(24,23,2#10); _ -> %% context-sensitive alias crap case {L,AddressingMode} of {1,'fa'} -> ?BF(24,23,2#00); {1,'fd'} -> ?BF(24,23,2#01); {1,'ea'} -> ?BF(24,23,2#10); {1,'ed'} -> ?BF(24,23,2#11); {0,'ed'} -> ?BF(24,23,2#00); {0,'ea'} -> ?BF(24,23,2#01); {0,'fd'} -> ?BF(24,23,2#10); {0,'fa'} -> ?BF(24,23,2#11) end end.am5_ls_coprocessor(AddressingMode) -> case AddressingMode of {offset,{r,Rn},Sign,{imm8,Imm8}} -> ?BIT(24,1) bor sign(Sign) bor ?BF(19,16,Rn) bor ?BF(7,0,Imm8); {pre_indexed,{r,Rn},Sign,{imm8,Imm8}} -> ?ASSERT(Rn =/= 15), % UNPREDICTABLE ?BIT(24,1) bor sign(Sign) bor ?BIT(21,1) bor ?BF(19,16,Rn) bor ?BF(7,0,Imm8); {post_indexed,{r,Rn},Sign,{imm8,Imm8}} -> ?ASSERT(Rn =/= 15), % UNPREDICTABLE sign(Sign) bor ?BIT(21,1) bor ?BF(19,16,Rn) bor ?BF(7,0,Imm8); {unindexed,{r,Rn},{imm8,Imm8}} -> ?BIT(23,1) bor ?BF(19,16,Rn) bor ?BF(7,0,Imm8) end.%%%'cond'(Cond) -> case Cond of 'eq' -> ?BF(31,28,2#0000); % equal 'ne' -> ?BF(31,28,2#0001); % not equal 'cs' -> ?BF(31,28,2#0010); % carry set 'hs' -> ?BF(31,28,2#0010); % unsigned higher or same 'cc' -> ?BF(31,28,2#0011); % carry clear 'lo' -> ?BF(31,28,2#0011); % unsigned lower 'mi' -> ?BF(31,28,2#0100); % minus/negative 'pl' -> ?BF(31,28,2#0101); % plus/positive or zero 'vs' -> ?BF(31,28,2#0110); % overflow 'vc' -> ?BF(31,28,2#0111); % no overflow 'hi' -> ?BF(31,28,2#1000); % unsigned higher 'ls' -> ?BF(31,28,2#1001); % unsigned lower or same 'ge' -> ?BF(31,28,2#1010); % signed greater than or equal 'lt' -> ?BF(31,28,2#1011); % signed less than 'gt' -> ?BF(31,28,2#1100); % signed greater than 'le' -> ?BF(31,28,2#1101); % signed less than or equal 'al' -> ?BF(31,28,2#1110) % always end.%%%%%% ARM Instructions%%%data_processing_form(Cond, OpCode, S, Rn, Rd, ShifterOperand) -> case S of 1 -> ?ASSERT(Rd =/= 15); % UNPREDICTABLE in User or System mode _ -> [] end, 'cond'(Cond) bor ?BF(24,21,OpCode) bor ?BIT(20,S) bor ?BF(19,16,Rn) bor ?BF(15,12,Rd) bor am1_shifter_operand(Rn,Rd,ShifterOperand).data_processing_form(OpCode, {{'cond',Cond},{s,S},{r,Rd},{r,Rn},ShifterOperand}) -> data_processing_form(Cond, OpCode, S, Rn, Rd, ShifterOperand).adc(Opnds) -> data_processing_form(2#0101, Opnds).add(Opnds) -> data_processing_form(2#0100, Opnds).'and'(Opnds) -> data_processing_form(2#0000, Opnds).bic(Opnds) -> data_processing_form(2#1110, Opnds).eor(Opnds) -> data_processing_form(2#0001, Opnds).orr(Opnds) -> data_processing_form(2#1100, Opnds).rsb(Opnds) -> data_processing_form(2#0011, Opnds).rsc(Opnds) -> data_processing_form(2#0111, Opnds).sbc(Opnds) -> data_processing_form(2#0110, Opnds).sub(Opnds) -> data_processing_form(2#0010, Opnds).cmp_form(OpCode, {{'cond',Cond},{r,Rn},ShifterOperand}) -> data_processing_form(Cond, OpCode, 1, Rn, 0, ShifterOperand).cmn(Opnds) -> cmp_form(2#1011, Opnds).cmp(Opnds) -> cmp_form(2#1010, Opnds).teq(Opnds) -> cmp_form(2#1001, Opnds).tst(Opnds) -> cmp_form(2#1000, Opnds).mov_form(OpCode, {{'cond',Cond},{s,S},{r,Rd},ShifterOperand}) -> data_processing_form(Cond, OpCode, S, 0, Rd, ShifterOperand).mov(Opnds) -> mov_form(2#1101, Opnds).mvn(Opnds) -> mov_form(2#1111, Opnds).%%%b_form(L, {{'cond',Cond},{imm24,Imm24}}) -> 'cond'(Cond) bor ?BF(27,25,2#101) bor ?BIT(24,L) bor ?BF(23,0,Imm24).b(Opnds) -> b_form(0, Opnds).bl(Opnds) -> b_form(1, Opnds).bkpt({{imm16,Imm16}}) -> ?BF(31,28,2#1110) bor ?BF(27,20,2#00010010) bor ?BF(19,8,Imm16 bsr 4) bor ?BF(7,4,2#0111) bor ?BF(3,0,Imm16 band 2#1111).bx_form(SubOpcode, {{'cond',Cond},{r,Rm}}, IsBlx) -> case IsBlx of true -> ?ASSERT(Rm =/= 15); % UNPREDICTABLE _ -> []
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?