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 + -
显示快捷键?