1%%% -*- erlang-indent-level: 2 -*- 2%%% 3%%% Licensed under the Apache License, Version 2.0 (the "License"); 4%%% you may not use this file except in compliance with the License. 5%%% You may obtain a copy of the License at 6%%% 7%%% http://www.apache.org/licenses/LICENSE-2.0 8%%% 9%%% Unless required by applicable law or agreed to in writing, software 10%%% distributed under the License is distributed on an "AS IS" BASIS, 11%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12%%% See the License for the specific language governing permissions and 13%%% limitations under the License. 14%%% 15%%% Encode symbolic ARM instructions to binary form. 16%%% Copyright (C) 2005 Mikael Pettersson 17%%% 18%%% Implementation Notes: 19%%% - The Thumb instruction set is a different entity, and is 20%%% not and never will be supported by this module. 21%%% - Instructions and instruction forms that are unpredictable 22%%% or useless in User mode are not supported. They include: 23%%% + Data Processing Instructions with S=1 and Rd=15. 24%%% + The LDM(2), LDM(3), and STM(2) instructions. 25%%% + MRS instructions that access the SPSR. 26%%% + MSR instructions that access the SPSR. 27%%% + The LDBRT, LDRT, STBRT, and STRT instructions. 28%%% 29%%% Instruction Operands: 30%%% 31%%% S ::= {s,0} | {s,1} 32%%% L ::= {l,0} | {l,1} 33%%% R ::= {r,RNum} 34%%% CR ::= {cr,CRNum} 35%%% 36%%% Cond ::= {cond,CondName} 37%%% CondName ::= eq | ne | cs | hs | cc | lo | mi | pl | vs 38%%% | vc | hi | ls | ge | lt | gt | ge | al 39%%% 40%%% Imm<N> ::= {imm<N>,<N bits>} for N in 4, 5, 8, 12, 16, 24, and 25 41%%% 42%%% Am1ShifterOperand 43%%% ::= {Imm8,Imm4} 44%%% | Rm 45%%% | {Rm,Am1ShiftOp} 46%%% Am1ShiftOp ::= {ShiftOp,Imm5} 47%%% | {ShiftOp,Rs} 48%%% | rrx 49%%% ShiftOp ::= lsl | lsr | asr | ror 50%%% 51%%% Am2LSWUBOperand ::= {immediate_offset,Rn,Sign,Imm12} 52%%% | {register_offset,Rn,Sign,Rm} // redundant 53%%% | {scaled_register_offset,Rn,Sign,Rm,Am2ShiftOp} 54%%% | {immediate_pre_indexed,Rn,Sign,Imm12} 55%%% | {register_pre_indexed,Rn,Sign,Rm} // redundant 56%%% | {scaled_register_pre_indexed,Rn,Sign,Rm,Am2ShiftOp} 57%%% | {immediate_post_indexed,Rn,Sign,Imm12} 58%%% | {register_post_indexed,Rn,Sign,Rm} // redundant 59%%% | {scaled_register_post_indexed,Rn,Sign,Rm,Am2ShiftOp} 60%%% Am2ShiftOp ::= {ShiftOp,Imm5} 61%%% | rrx 62%%% Sign ::= + | - 63%%% 64%%% Am3MiscLSOperand::= {immediate_offset,Rn,Sign,Imm8} 65%%% | {register_offset,Rn,Sign,Rm} 66%%% | {immediate_pre_indexed,Rn,Sign,Imm8} 67%%% | {register_pre_indexed,Rn,Sign,Rm} 68%%% | {immediate_post_indexed,Rn,Sign,Imm8} 69%%% | {register_post_indexed,Rn,Sign,Rm} 70%%% 71%%% Am4LSMultiple ::= ia | ib | da | db 72%%% | fd | ed | fa | ea 73%%% 74%%% Am5LSCoprocessor::= {offset,Rn,Sign,Imm8} 75%%% | {pre_indexed,Rn,Sign,Imm8} 76%%% | {post_indexed,Rn,Sign,Imm8} 77%%% | {unindexed,Rn,Imm8} 78 79-module(hipe_arm_encode). 80 81-export([insn_encode/2]). 82 83%%-define(TESTING,1). 84-ifdef(TESTING). 85-export([dotest/0, dotest/1]). 86-endif. 87 88-define(ASSERT(G), 89 if G -> []; 90 true -> exit({assertion_failed,?MODULE,?LINE,??G}) 91 end). 92 93bf(LeftBit, RightBit, Value) -> 94 ?ASSERT(32 > LeftBit), 95 ?ASSERT(LeftBit >= RightBit), 96 ?ASSERT(RightBit >= 0), 97 ?ASSERT(Value >= 0), 98 ?ASSERT(Value < (1 bsl ((LeftBit - RightBit) + 1))), 99 Value bsl RightBit. 100 101-define(BF(LB,RB,V), bf(LB,RB,V)). 102-define(BIT(Pos,Val), ?BF(Pos,Pos,Val)). 103%%-define(BITS(N,Val), ?BF(N,0,Val)). 104 105%%% 106%%% Addressing Modes 107%%% 108 109am1_shifter_operand(Rn, Rd, ShifterOperand) -> 110 case ShifterOperand of 111 {{imm8,Imm8},{imm4,RotImm4}} -> 112 ?BIT(25,1) bor ?BF(11,8,RotImm4) bor ?BF(7,0,Imm8); 113 {r,Rm} -> 114 %% same as Rm LSL #0 115 ?BF(3,0,Rm); 116 {{r,Rm},ShiftOp} -> 117 am1_shift_op(Rn, Rd, Rm, ShiftOp) bor ?BF(3,0,Rm) 118 end. 119 120am1_shift_op(_Rn, _Rd, _Rm, {ShiftOp,{imm5,ShiftImm5}}) -> 121 case ShiftOp of 122 'ror' -> ?ASSERT(ShiftImm5 =/= 0); % denotes RRX form 123 _ -> [] 124 end, 125 ?BF(11,7,ShiftImm5) bor shift_op_bits65(ShiftOp); 126am1_shift_op(Rn, Rd, Rm, {ShiftOp,{r,Rs}}) -> 127 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 128 ?ASSERT(Rd =/= 15), % UNPREDICTABLE 129 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 130 ?ASSERT(Rs =/= 15), % UNPREDICTABLE 131 ?BF(11,8,Rs) bor shift_op_bits65(ShiftOp) bor ?BIT(4,1); 132am1_shift_op(_Rn, _Rd, _Rm, 'rrx') -> 133 ?BF(6,5,2#11). 134 135shift_op_bits65(ShiftOp) -> 136 case ShiftOp of 137 'lsl' -> ?BF(6,5,2#00); 138 'lsr' -> ?BF(6,5,2#01); 139 'asr' -> ?BF(6,5,2#10); 140 'ror' -> ?BF(6,5,2#11) 141 end. 142 143sign('+') -> ?BIT(23,1); 144sign('-') -> 0. 145 146am2_lswub(Rd, AddressingMode) -> 147 case AddressingMode of 148 {immediate_offset,{r,Rn},Sign,{imm12,Imm12}} -> 149 ?BIT(24,1) bor sign(Sign) bor ?BF(19,16,Rn) bor ?BF(11,0,Imm12); 150 {register_offset,{r,Rn},Sign,{r,Rm}} -> 151 %% same as scaled_register_offset LSL #0 152 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 153 ?BIT(25,1) bor ?BIT(24,1) bor sign(Sign) bor ?BF(19,16,Rn) bor ?BF(3,0,Rm); 154 {scaled_register_offset,{r,Rn},Sign,{r,Rm},ShiftOp} -> 155 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 156 ?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); 157 {immediate_pre_indexed,{r,Rn},Sign,{imm12,Imm12}} -> 158 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE 159 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 160 ?BIT(24,1) bor sign(Sign) bor ?BIT(21,1) bor ?BF(19,16,Rn) bor ?BF(11,0,Imm12); 161 {register_pre_indexed,{r,Rn},Sign,{r,Rm}} -> 162 %% same as scaled_register_pre_indexed LSL #0 163 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE 164 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 165 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 166 ?ASSERT(Rn =/= Rm), % UNPREDICTABLE 167 ?BIT(25,1) bor ?BIT(24,1) bor sign(Sign) bor ?BIT(21,1) bor ?BF(19,16,Rn) bor ?BF(3,0,Rm); 168 {scaled_register_pre_indexed,{r,Rn},Sign,{r,Rm},ShiftOp} -> 169 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE 170 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 171 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 172 ?ASSERT(Rn =/= Rm), % UNPREDICTABLE 173 ?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); 174 {immediate_post_indexed,{r,Rn},Sign,{imm12,Imm12}} -> 175 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE 176 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 177 sign(Sign) bor ?BF(19,16,Rn) bor ?BF(11,0,Imm12); 178 {register_post_indexed,{r,Rn},Sign,{r,Rm}} -> 179 %% same as scaled_register_post_indexed LSL #0 180 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE 181 ?BIT(25,1) bor sign(Sign) bor ?BF(19,6,Rn) bor ?BF(3,0,Rm); 182 {scaled_register_post_indexed,{r,Rn},Sign,{r,Rm},ShiftOp} -> 183 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE 184 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 185 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 186 ?ASSERT(Rn =/= Rm), % UNPREDICTABLE 187 ?BIT(25,1) bor sign(Sign) bor ?BF(19,16,Rn) bor am2_shift_op(ShiftOp) bor ?BF(3,0,Rm) 188 end. 189 190am2_shift_op({ShiftOp,{imm5,ShiftImm5}}) -> 191 case ShiftOp of 192 'ror' -> ?ASSERT(ShiftImm5 =/= 0); % denotes RRX form 193 _ -> [] 194 end, 195 ?BF(11,7,ShiftImm5) bor shift_op_bits65(ShiftOp); 196am2_shift_op('rrx') -> 197 ?BF(6,5,2#11). 198 199am3_miscls(Rd, AddressingMode) -> 200 case AddressingMode of 201 {immediate_offset,{r,Rn},Sign,{imm8,Imm8}} -> 202 ?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); 203 {register_offset,{r,Rn},Sign,{r,Rm}} -> 204 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 205 ?BIT(24,1) bor sign(Sign) bor ?BF(22,21,2#00) bor ?BF(19,16,Rn) bor ?BF(3,0,Rm); 206 {immediate_pre_indexed,{r,Rn},Sign,{imm8,Imm8}} -> 207 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE 208 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 209 ?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); 210 {register_pre_indexed,{r,Rn},Sign,{r,Rm}} -> 211 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE 212 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 213 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 214 ?ASSERT(Rm =/= Rn), % UNPREDICTABLE 215 ?BIT(24,1) bor sign(Sign) bor ?BF(22,21,2#01) bor ?BF(19,16,Rn) bor ?BF(3,0,Rm); 216 {immediate_post_indexed,{r,Rn},Sign,{imm8,Imm8}} -> 217 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE 218 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 219 ?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); 220 {register_post_indexed,{r,Rn},Sign,{r,Rm}} -> 221 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE 222 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 223 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 224 ?ASSERT(Rm =/= Rn), % UNPREDICTABLE 225 ?BIT(24,0) bor sign(Sign) bor ?BF(22,21,2#00) bor ?BF(19,16,Rn) bor ?BF(3,0,Rm) 226 end. 227 228am4_ls_multiple(L, AddressingMode) -> 229 case AddressingMode of 230 'ia' -> ?BF(24,23,2#01); 231 'ib' -> ?BF(24,23,2#11); 232 'da' -> ?BF(24,23,2#00); 233 'db' -> ?BF(24,23,2#10); 234 _ -> 235 %% context-sensitive alias crap 236 case {L,AddressingMode} of 237 {1,'fa'} -> ?BF(24,23,2#00); 238 {1,'fd'} -> ?BF(24,23,2#01); 239 {1,'ea'} -> ?BF(24,23,2#10); 240 {1,'ed'} -> ?BF(24,23,2#11); 241 {0,'ed'} -> ?BF(24,23,2#00); 242 {0,'ea'} -> ?BF(24,23,2#01); 243 {0,'fd'} -> ?BF(24,23,2#10); 244 {0,'fa'} -> ?BF(24,23,2#11) 245 end 246 end. 247 248am5_ls_coprocessor(AddressingMode) -> 249 case AddressingMode of 250 {offset,{r,Rn},Sign,{imm8,Imm8}} -> 251 ?BIT(24,1) bor sign(Sign) bor ?BF(19,16,Rn) bor ?BF(7,0,Imm8); 252 {pre_indexed,{r,Rn},Sign,{imm8,Imm8}} -> 253 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 254 ?BIT(24,1) bor sign(Sign) bor ?BIT(21,1) bor ?BF(19,16,Rn) bor ?BF(7,0,Imm8); 255 {post_indexed,{r,Rn},Sign,{imm8,Imm8}} -> 256 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 257 sign(Sign) bor ?BIT(21,1) bor ?BF(19,16,Rn) bor ?BF(7,0,Imm8); 258 {unindexed,{r,Rn},{imm8,Imm8}} -> 259 ?BIT(23,1) bor ?BF(19,16,Rn) bor ?BF(7,0,Imm8) 260 end. 261 262%%% 263 264'cond'(Cond) -> 265 case Cond of 266 'eq' -> ?BF(31,28,2#0000); % equal 267 'ne' -> ?BF(31,28,2#0001); % not equal 268 'cs' -> ?BF(31,28,2#0010); % carry set 269 'hs' -> ?BF(31,28,2#0010); % unsigned higher or same 270 'cc' -> ?BF(31,28,2#0011); % carry clear 271 'lo' -> ?BF(31,28,2#0011); % unsigned lower 272 'mi' -> ?BF(31,28,2#0100); % minus/negative 273 'pl' -> ?BF(31,28,2#0101); % plus/positive or zero 274 'vs' -> ?BF(31,28,2#0110); % overflow 275 'vc' -> ?BF(31,28,2#0111); % no overflow 276 'hi' -> ?BF(31,28,2#1000); % unsigned higher 277 'ls' -> ?BF(31,28,2#1001); % unsigned lower or same 278 'ge' -> ?BF(31,28,2#1010); % signed greater than or equal 279 'lt' -> ?BF(31,28,2#1011); % signed less than 280 'gt' -> ?BF(31,28,2#1100); % signed greater than 281 'le' -> ?BF(31,28,2#1101); % signed less than or equal 282 'al' -> ?BF(31,28,2#1110) % always 283 end. 284 285%%% 286%%% ARM Instructions 287%%% 288 289data_processing_form(Cond, OpCode, S, Rn, Rd, ShifterOperand) -> 290 case S of 291 1 -> ?ASSERT(Rd =/= 15); % UNPREDICTABLE in User or System mode 292 _ -> [] 293 end, 294 '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). 295 296data_processing_form(OpCode, {{'cond',Cond},{s,S},{r,Rd},{r,Rn},ShifterOperand}) -> 297 data_processing_form(Cond, OpCode, S, Rn, Rd, ShifterOperand). 298 299adc(Opnds) -> data_processing_form(2#0101, Opnds). 300add(Opnds) -> data_processing_form(2#0100, Opnds). 301'and'(Opnds) -> data_processing_form(2#0000, Opnds). 302bic(Opnds) -> data_processing_form(2#1110, Opnds). 303eor(Opnds) -> data_processing_form(2#0001, Opnds). 304orr(Opnds) -> data_processing_form(2#1100, Opnds). 305rsb(Opnds) -> data_processing_form(2#0011, Opnds). 306rsc(Opnds) -> data_processing_form(2#0111, Opnds). 307sbc(Opnds) -> data_processing_form(2#0110, Opnds). 308sub(Opnds) -> data_processing_form(2#0010, Opnds). 309 310cmp_form(OpCode, {{'cond',Cond},{r,Rn},ShifterOperand}) -> 311 data_processing_form(Cond, OpCode, 1, Rn, 0, ShifterOperand). 312 313cmn(Opnds) -> cmp_form(2#1011, Opnds). 314cmp(Opnds) -> cmp_form(2#1010, Opnds). 315teq(Opnds) -> cmp_form(2#1001, Opnds). 316tst(Opnds) -> cmp_form(2#1000, Opnds). 317 318mov_form(OpCode, {{'cond',Cond},{s,S},{r,Rd},ShifterOperand}) -> 319 data_processing_form(Cond, OpCode, S, 0, Rd, ShifterOperand). 320 321mov(Opnds) -> mov_form(2#1101, Opnds). 322mvn(Opnds) -> mov_form(2#1111, Opnds). 323 324%%% 325 326b_form(L, {{'cond',Cond},{imm24,Imm24}}) -> 327 'cond'(Cond) bor ?BF(27,25,2#101) bor ?BIT(24,L) bor ?BF(23,0,Imm24). 328 329b(Opnds) -> b_form(0, Opnds). 330bl(Opnds) -> b_form(1, Opnds). 331 332bkpt({{imm16,Imm16}}) -> 333 ?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). 334 335bx_form(SubOpcode, {{'cond',Cond},{r,Rm}}, IsBlx) -> 336 case IsBlx of 337 true -> ?ASSERT(Rm =/= 15); % UNPREDICTABLE 338 _ -> [] 339 end, 340 'cond'(Cond) bor ?BF(27,20,2#00010010) bor ?BF(19,16,2#1111) bor ?BF(15,12,2#1111) bor ?BF(11,8,2#1111) bor ?BF(7,4,SubOpcode) bor ?BF(3,0,Rm). 341 342blx(Opnds) -> 343 case Opnds of 344 {{imm25,Imm25}} -> % u16-offset! 345 ?BF(31,28,2#1111) bor ?BF(27,25,2#101) bor ?BIT(24,Imm25 band 1) bor ?BF(23,0,Imm25 bsr 1); 346 _ -> 347 bx_form(2#0011, Opnds, true) 348 end. 349 350bx(Opnds) -> bx_form(2#0001, Opnds, false). 351 352cdp_form(Cond, CpOp4, CRn, CRd, CpNum, CpOp3, CRm) -> 353 Cond bor ?BF(27,24,2#1110) bor ?BF(23,20,CpOp4) bor ?BF(19,16,CRn) bor ?BF(15,12,CRd) bor ?BF(11,8,CpNum) bor ?BF(7,5,CpOp3) bor ?BF(3,0,CRm). 354 355cdp({{'cond',Cond},{cpnum,CpNum},{cpop4,CpOp4},{cr,CRd},{cr,CRn},{cr,CRm},{cpop3,CpOp3}}) -> 356 cdp_form('cond'(Cond), CpOp4, CRn, CRd, CpNum, CpOp3, CRm). 357 358cdp2({{cpnum,CpNum},{cpop4,CpOp4},{cr,CRd},{cr,CRn},{cr,CRm},{cpop3,CpOp3}}) -> 359 cdp_form(?BF(31,28,2#1111), CpOp4, CRn, CRd, CpNum, CpOp3, CRm). 360 361clz({{'cond',Cond},{r,Rd},{r,Rm}}) -> 362 ?ASSERT(Rd =/= 15), % UNPREDICTABLE 363 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 364 'cond'(Cond) bor ?BF(27,20,2#00010110) bor ?BF(19,16,2#1111) bor ?BF(15,12,Rd) bor ?BF(11,8,2#1111) bor ?BF(7,4,2#0001) bor ?BF(3,0,Rm). 365 366ldstc_form(Cond, L, B20, CRd, CpNum, AddressingMode) -> 367 Cond bor ?BF(27,25,2#110) bor ?BIT(22,L) bor ?BIT(20,B20) bor ?BF(15,12,CRd) bor ?BF(11,8,CpNum) bor am5_ls_coprocessor(AddressingMode). 368 369ldstc(B20, {{'cond',Cond},{l,L},{cpnum,CpNum},{cr,CRd},AddressingMode}) -> 370 ldstc_form('cond'(Cond), L, B20, CRd, CpNum, AddressingMode). 371 372ldc(Opnds) -> ldstc(1, Opnds). 373stc(Opnds) -> ldstc(0, Opnds). 374 375ldstc2(B20, {{l,L},{cpnum,CpNum},{cr,CRd},AddressingMode}) -> 376 ldstc_form(?BF(31,28,2#1111), L, B20, CRd, CpNum, AddressingMode). 377 378ldc2(Opnds) -> ldstc2(1, Opnds). 379stc2(Opnds) -> ldstc2(0, Opnds). 380 381ldstm_form(Cond, AddressingMode, W, L, Rn, Registers) -> 382 RegisterList = register_list(Registers), 383 ?ASSERT(RegisterList =/= 0), % UNPREDICTABLE 384 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 385 case W of 386 1 -> 387 BitRn = 1 bsl Rn, 388 case L of 389 1 -> 390 %% LDM! Rn in Registers is UNPREDICTABLE 391 ?ASSERT((RegisterList band BitRn) =:= 0); 392 0 -> 393 %% STM! Rn in Registers and not lowest is UNPREDICTABLE 394 case RegisterList band BitRn of 395 0 -> []; 396 _ -> 397 ?ASSERT((RegisterList band (-RegisterList)) =:= BitRn) 398 end 399 end; 400 _ -> [] 401 end, 402 'cond'(Cond) bor ?BF(27,25,2#100) bor am4_ls_multiple(L, AddressingMode) bor ?BIT(21,W) bor ?BIT(20,L) bor ?BF(19,16,Rn) bor ?BF(15,0,RegisterList). 403 404register_list(Registers) -> register_list(Registers, 0). 405 406register_list([{r,R}|Rs], Mask) -> register_list(Rs, Mask bor (1 bsl R)); 407register_list([], Mask) -> Mask. 408 409ldstm(L, Opnds) -> 410 case Opnds of 411 {{'cond',Cond},AddressingMode,{r,Rn},'!',Registers} -> 412 ldstm_form(Cond, AddressingMode, 1, L, Rn, Registers); 413 {{'cond',Cond},AddressingMode,{r,Rn},Registers} -> 414 ldstm_form(Cond, AddressingMode, 0, L, Rn, Registers) 415 %% the ldm(2), ldm(3), and stm(2) forms are UNPREDICTABLE 416 %% in User or System mode 417 end. 418 419ldm(Opnds) -> ldstm(1, Opnds). 420stm(Opnds) -> ldstm(0, Opnds). 421 422ldstr_form2(B, L, {{'cond',Cond},{r,Rd},AddressingMode}) -> 423 'cond'(Cond) bor ?BF(27,26,2#01) bor am2_lswub(Rd, AddressingMode) bor ?BIT(22,B) bor ?BIT(20,L) bor ?BF(15,12,Rd). 424 425ldr(Opnds) -> ldstr_form2(0, 1, Opnds). 426ldrb(Opnds) -> ldstr_form2(1, 1, Opnds). 427str(Opnds) -> ldstr_form2(0, 0, Opnds). 428strb(Opnds) -> ldstr_form2(1, 0, Opnds). 429 430ldstr_form3(L, SubOpcode, {{'cond',Cond},{r,Rd},AddressingMode}) -> 431 ?ASSERT(Rd =/= 15), % UNPREDICTABLE 432 'cond'(Cond) bor am3_miscls(Rd, AddressingMode) bor ?BIT(20,L) bor ?BF(15,12,Rd) bor ?BF(7,4,SubOpcode). 433 434ldrh(Opnds) -> ldstr_form3(1, 2#1011, Opnds). 435ldrsb(Opnds) -> ldstr_form3(1, 2#1101, Opnds). 436ldrsh(Opnds) -> ldstr_form3(1, 2#1111, Opnds). 437strh(Opnds) -> ldstr_form3(0, 2#1011, Opnds). 438 439mcr_form(Cond, OP1, CRn, Rd, CpNum, OP2, CRm) -> 440 ?ASSERT(Rd =/= 15), % UNPREDICTABLE 441 Cond bor ?BF(27,24,2#1110) bor ?BF(23,21,OP1) bor ?BF(19,16,CRn) bor ?BF(15,12,Rd) bor ?BF(11,8,CpNum) bor ?BF(7,5,OP2) bor ?BIT(4,1) bor ?BF(3,0,CRm). 442 443mcr({{'cond',Cond},{cpnum,CpNum},{cpop3,OP1},{r,Rd},{cr,CRn},{cr,CRm},{cpop3,OP2}}) -> 444 mcr_form('cond'(Cond), OP1, CRn, Rd, CpNum, OP2, CRm). 445 446mcr2({{cpnum,CpNum},{cpop3,OP1},{r,Rd},{cr,CRn},{cr,CRm},{cpop3,OP2}}) -> 447 mcr_form(?BF(31,28,2#1111), OP1, CRn, Rd, CpNum, OP2, CRm). 448 449mla({{'cond',Cond},{s,S},{r,Rd},{r,Rm},{r,Rs},{r,Rn}}) -> 450 ?ASSERT(Rd =/= 15), % UNPREDICTABLE 451 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 452 ?ASSERT(Rs =/= 15), % UNPREDICTABLE 453 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 454 ?ASSERT(Rd =/= Rm), % UNPREDICTABLE 455 'cond'(Cond) bor ?BIT(21,1) bor ?BIT(20,S) bor ?BF(19,16,Rd) bor ?BF(15,12,Rn) bor ?BF(11,8,Rs) bor ?BF(7,4,2#1001) bor ?BF(3,0,Rm). 456 457mrc_form(Cond, OP1, CRn, Rd, CpNum, OP2, CRm) -> 458 Cond bor ?BF(27,24,2#1110) bor ?BF(23,21,OP1) bor ?BIT(20,1) bor ?BF(19,16,CRn) bor ?BF(15,12,Rd) bor ?BF(11,8,CpNum) bor ?BF(7,5,OP2) bor ?BIT(4,1) bor ?BF(3,0,CRm). 459 460mrc({{'cond',Cond},{cpnum,CpNum},{cpop3,OP1},{r,Rd},{cr,CRn},{cr,CRm},{cpop3,OP2}}) -> 461 mrc_form('cond'(Cond), OP1, CRn, Rd, CpNum, OP2, CRm). 462 463mrc2({{cpnum,CpNum},{cpop3,OP1},{r,Rd},{cr,CRn},{cr,CRm},{cpop3,OP2}}) -> 464 mrc_form(?BF(31,28,2#1111), OP1, CRn, Rd, CpNum, OP2, CRm). 465 466mrs({{'cond',Cond},{r,Rd},'cpsr'}) -> 467 %% the SPSR form is UNPREDICTABLE in User or System mode 468 ?ASSERT(Rd =/= 15), % UNPREDICTABLE 469 'cond'(Cond) bor ?BIT(24,1) bor ?BF(19,16,2#1111) bor ?BF(15,12,Rd). 470 471msr_form(Cond, FieldMask4, Operand) -> 472 'cond'(Cond) bor ?BIT(24,1) bor ?BIT(21,1) bor ?BF(19,16,FieldMask4) bor ?BF(15,12,2#1111) bor Operand. 473 474msr(Opnds) -> 475 %% the SPSR form is UNPREDICTABLE in User or System mode 476 case Opnds of 477 {{'cond',Cond},'cpsr',{field_mask,FieldMask4},{imm8,Imm8},{imm4,RotImm4}} -> 478 msr_form(Cond, FieldMask4, ?BIT(25,1) bor ?BF(11,8,RotImm4) bor ?BF(7,0,Imm8)); 479 {{'cond',Cond},'cpsr',{field_mask,FieldMask4},{r,Rm}} -> 480 msr_form(Cond, FieldMask4, ?BF(3,0,Rm)) 481 end. 482 483mul({{'cond',Cond},{s,S},{r,Rd},{r,Rm},{r,Rs}}) -> 484 ?ASSERT(Rd =/= 15), % UNPREDICTABLE 485 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 486 ?ASSERT(Rs =/= 15), % UNPREDICTABLE 487 ?ASSERT(Rd =/= Rm), % UNPREDICTABLE 488 'cond'(Cond) bor ?BIT(20,S) bor ?BF(19,16,Rd) bor ?BF(11,8,Rs) bor ?BF(7,4,2#1001) bor ?BF(3,0,Rm). 489 490ml_form2(OpCode, Cond, S, RdLo, RdHi, Rm, Rs) -> 491 ?ASSERT(RdHi =/= 15), % UNPREDICTABLE 492 ?ASSERT(RdLo =/= 15), % UNPREDICTABLE 493 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 494 ?ASSERT(Rs =/= 15), % UNPREDICTABLE 495 ?ASSERT(RdHi =/= RdLo),% UNPREDICTABLE 496 ?ASSERT(RdHi =/= Rm), % UNPREDICTABLE 497 ?ASSERT(RdLo =/= Rm), % UNPREDICTABLE 498 'cond'(Cond) bor ?BF(27,21,OpCode) bor ?BIT(20,S) bor ?BF(19,16,RdHi) bor ?BF(15,12,RdLo) bor ?BF(11,8,Rs) bor ?BF(7,4,2#1001) bor ?BF(3,0,Rm). 499 500ml_form(OpCode, {{'cond',Cond},{s,S},{r,RdLo},{r,RdHi},{r,Rm},{r,Rs}}) -> 501 ml_form2(OpCode, Cond, S, RdLo, RdHi, Rm, Rs). 502 503%%smlal(Opnds) -> ml_form(2#0000111, Opnds). 504smull(Opnds) -> ml_form(2#0000110, Opnds). 505umlal(Opnds) -> ml_form(2#0000101, Opnds). 506umull(Opnds) -> ml_form(2#0000100, Opnds). 507 508swi({{'cond',Cond},{imm24,Imm24}}) -> 509 'cond'(Cond) bor ?BF(27,24,2#1111) bor ?BF(23,0,Imm24). 510 511swp_form(B22, {{'cond',Cond},{r,Rd},{r,Rm},{r,Rn}}) -> 512 ?ASSERT(Rd =/= 15), % UNPREDICTABLE 513 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 514 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 515 ?ASSERT(Rn =/= Rm), % UNPREDICTABLE 516 ?ASSERT(Rn =/= Rd), % UNPREDICTABLE 517 'cond'(Cond) bor ?BIT(24,1) bor ?BIT(22,B22) bor ?BF(19,16,Rn) bor ?BF(15,12,Rd) bor ?BF(7,4,2#1001) bor ?BF(3,0,Rm). 518 519swp(Opnds) -> swp_form(0, Opnds). 520swpb(Opnds) -> swp_form(1, Opnds). 521 522%%% 523%%% Enhanced DSP Extension Instructions 524%%% 525 526ldstrd_form(OpCode, {{'cond',Cond},{r,Rd},AddressingMode}) -> 527 ?ASSERT(Rd =/= 14), % UNPREDICTABLE 528 ?ASSERT((Rd band 1) =:= 0), % UNDEFINED 529 %% XXX: unpredictable if write-back and base reg Rn equals Rd or Rd+1 530 %% XXX: if is load then unpredictable if index reg Rm and Rm equals Rd or Rd+1 531 'cond'(Cond) bor am3_miscls(Rd, AddressingMode) bor ?BF(15,12,Rd) bor ?BF(7,4,OpCode). 532 533ldrd(Opnds) -> ldstrd_form(2#1101, Opnds). 534strd(Opnds) -> ldstrd_form(2#1111, Opnds). 535 536mcrr({{'cond',Cond},{cpnum,CpNum},{cpop4,OP},{r,Rd},{r,Rn},{cr,CRm}}) -> 537 ?ASSERT(Rd =/= 15), % UNPREDICTABLE 538 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 539 'cond'(Cond) bor ?BF(27,20,2#11000100) bor ?BF(19,16,Rn) bor ?BF(15,12,Rd) bor ?BF(11,8,CpNum) bor ?BF(7,4,OP) bor ?BF(3,0,CRm). 540 541mrrc({{'cond',Cond},{cpnum,CpNum},{cpop4,OP},{r,Rd},{r,Rn},{cr,CRm}}) -> 542 ?ASSERT(Rd =/= 15), % UNPREDICTABLE 543 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 544 ?ASSERT(Rd =/= Rn), % UNPREDICTABLE 545 'cond'(Cond) bor ?BF(27,20,2#11000101) bor ?BF(19,16,Rn) bor ?BF(15,12,Rd) bor ?BF(11,8,CpNum) bor ?BF(7,4,OP) bor ?BF(3,0,CRm). 546 547pld({AddressingMode}) -> 548 AM = am2_lswub(42, AddressingMode), % 42 is a dummy reg nr 549 %% not all adressing modes are allowed: bit 24 must be 1 550 %% and bit 21 must be 0 551 ?ASSERT(((AM bsr 21) band 2#1001) =:= 2#1000), 552 16#F550F000 bor AM. 553 554q_form(OpCode, {{'cond',Cond},{r,Rd},{r,Rm},{r,Rn}}) -> 555 ?ASSERT(Rd =/= 15), % UNPREDICTABLE 556 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 557 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 558 'cond'(Cond) bor ?BF(27,20,OpCode) bor ?BF(19,16,Rn) bor ?BF(15,11,Rd) bor ?BF(7,4,2#0101) bor ?BF(3,0,Rm). 559 560qadd(Opnds) -> q_form(2#00010000, Opnds). 561qdadd(Opnds) -> q_form(2#00010100, Opnds). 562qdsub(Opnds) -> q_form(2#00010110, Opnds). 563qsub(Opnds) -> q_form(2#00010010, Opnds). 564 565smlaxy_form(Cond, OpCode, Rd, Rn, Rs, Y, X, Rm) -> 566 ?ASSERT(Rd =/= 15), % UNPREDICTABLE 567 ?ASSERT(Rm =/= 15), % UNPREDICTABLE 568 ?ASSERT(Rs =/= 15), % UNPREDICTABLE 569 ?ASSERT(Rn =/= 15), % UNPREDICTABLE 570 'cond'(Cond) bor ?BF(27,20,OpCode) bor ?BF(19,16,Rd) bor ?BF(15,12,Rn) bor ?BF(11,8,Rs) bor ?BIT(7,1) bor ?BIT(6,Y) bor ?BIT(5,X) bor ?BF(3,0,Rm). 571 572smla({{bt,X},{bt,Y},{'cond',Cond},{r,Rd},{r,Rm},{r,Rs},{r,Rn}}) -> 573 smlaxy_form(Cond, 2#00010000, Rd, Rn, Rs, Y, X, Rm). 574 575smlal(Opnds) -> % may be regular ARM or DSP insn :-( 576 case Opnds of 577 {{'cond',Cond},{s,S},{r,RdLo},{r,RdHi},{r,Rm},{r,Rs}} -> 578 ml_form2(2#0000111, Cond, S, RdLo, RdHi, Rm, Rs); 579 {{bt,X},{bt,Y},{'cond',Cond},{r,RdLo},{r,RdHi},{r,Rm},{r,Rs}} -> 580 ?ASSERT(RdLo =/= RdHi), % UNPREDICTABLE 581 smlaxy_form(Cond, 2#00010100, RdHi, RdLo, Rs, Y, X, Rm) 582 end. 583 584smlaw({{bt,Y},{'cond',Cond},{r,Rd},{r,Rm},{r,Rs},{r,Rn}}) -> 585 smlaxy_form(Cond, 2#00010010, Rd, Rn, Rs, Y, 0, Rm). 586 587smul({{bt,X},{bt,Y},{'cond',Cond},{r,Rd},{r,Rm},{r,Rs}}) -> 588 smlaxy_form(Cond, 2#00010110, Rd, 0, Rs, Y, X, Rm). 589 590smulw({{bt,Y},{'cond',Cond},{r,Rd},{r,Rm},{r,Rs}}) -> 591 smlaxy_form(Cond, 2#00010010, Rd, 0, Rs, Y, 1, Rm). 592 593%%% 594%%% Main Encode Dispatch 595%%% 596 597insn_encode(Op, Opnds) -> 598 case Op of 599 'adc' -> adc(Opnds); 600 'add' -> add(Opnds); 601 'and' -> 'and'(Opnds); 602 'b' -> b(Opnds); 603 'bic' -> bic(Opnds); 604 'bkpt' -> bkpt(Opnds); 605 'bl' -> bl(Opnds); 606 'blx' -> blx(Opnds); 607 'bx' -> bx(Opnds); 608 'cdp' -> cdp(Opnds); 609 'cdp2' -> cdp2(Opnds); 610 'clz' -> clz(Opnds); 611 'cmn' -> cmn(Opnds); 612 'cmp' -> cmp(Opnds); 613 'eor' -> eor(Opnds); 614 'ldc' -> ldc(Opnds); 615 'ldc2' -> ldc2(Opnds); 616 'ldm' -> ldm(Opnds); 617 'ldr' -> ldr(Opnds); 618 'ldrb' -> ldrb(Opnds); 619 'ldrd' -> ldrd(Opnds); 620 %% ldrbt: omitted 621 'ldrh' -> ldrh(Opnds); 622 'ldrsb' -> ldrsb(Opnds); 623 'ldrsh' -> ldrsh(Opnds); 624 %% ldrt: omitted 625 'mcr' -> mcr(Opnds); 626 'mcr2' -> mcr2(Opnds); 627 'mcrr' -> mcrr(Opnds); 628 'mla' -> mla(Opnds); 629 'mov' -> mov(Opnds); 630 'mrc' -> mrc(Opnds); 631 'mrc2' -> mrc2(Opnds); 632 'mrrc' -> mrrc(Opnds); 633 'mrs' -> mrs(Opnds); 634 'msr' -> msr(Opnds); 635 'mul' -> mul(Opnds); 636 'mvn' -> mvn(Opnds); 637 'orr' -> orr(Opnds); 638 'pld' -> pld(Opnds); 639 'qadd' -> qadd(Opnds); 640 'qdadd' -> qdadd(Opnds); 641 'qdsub' -> qdsub(Opnds); 642 'qsub' -> qsub(Opnds); 643 'rsb' -> rsb(Opnds); 644 'rsc' -> rsc(Opnds); 645 'sbc' -> sbc(Opnds); 646 'smla' -> smla(Opnds); 647 'smlal' -> smlal(Opnds); % may be regular ARM or DSP insn :-( 648 'smlaw' -> smlaw(Opnds); 649 'smull' -> smull(Opnds); 650 'smul' -> smul(Opnds); 651 'smulw' -> smulw(Opnds); 652 'stc' -> stc(Opnds); 653 'stc2' -> stc2(Opnds); 654 'stm' -> stm(Opnds); 655 'str' -> str(Opnds); 656 'strb' -> strb(Opnds); 657 %% strbt: omitted 658 'strd' -> strd(Opnds); 659 'strh' -> strh(Opnds); 660 %% strt: omitted 661 'sub' -> sub(Opnds); 662 'swi' -> swi(Opnds); 663 'swp' -> swp(Opnds); 664 'swpb' -> swpb(Opnds); 665 'teq' -> teq(Opnds); 666 'tst' -> tst(Opnds); 667 'umlal' -> umlal(Opnds); 668 'umull' -> umull(Opnds); 669 _ -> exit({?MODULE,insn_encode,Op}) 670 end. 671 672%%% 673%%% Testing Interface 674%%% 675 676-ifdef(TESTING). 677 678say(OS, Str) -> 679 file:write(OS, Str). 680 681hex_digit(Dig0) -> 682 Dig = Dig0 band 16#F, 683 if Dig >= 16#A -> $A + (Dig - 16#A); 684 true -> $0 + Dig 685 end. 686 687say_byte(OS, Byte) -> 688 say(OS, [hex_digit(Byte bsr 4)]), 689 say(OS, [hex_digit(Byte)]). 690 691say_word(OS, Word) -> 692 say(OS, "0x"), 693 say_byte(OS, Word bsr 24), 694 say_byte(OS, Word bsr 16), 695 say_byte(OS, Word bsr 8), 696 say_byte(OS, Word). 697 698t(OS, Op, Opnds) -> 699 Word = insn_encode(Op, Opnds), 700 say(OS, "\t.long "), 701 say_word(OS, Word), 702 say(OS, "\n"). 703 704dotest1(OS) -> 705 say(OS, "\t.text\n\t.align 4\n"), 706 %% 707 Rn = {r,9}, 708 Rd = {r,8}, % must be even and less than 14 for some insns 709 Rm = {r,7}, 710 Rs = {r,6}, 711 RdLo = Rn, 712 RdHi = Rd, 713 Registers = [Rm,Rs,Rd], % must exclude Rn for some insns 714 CRd = {cr,15}, 715 CRn = {cr,14}, 716 CRm = {cr,13}, 717 BT0 = {bt,0}, 718 BT1 = {bt,1}, 719 CpNum = {cpnum,15}, 720 CpOp3 = {cpop3,16#3}, 721 CpOp4 = {cpop4,16#F}, 722 L0 = {l,0}, 723 L1 = {l,1}, 724 S0 = {s,0}, 725 S1 = {s,1}, 726 FieldMask4 = {field_mask,16#F}, 727 Imm4 = {imm4,16#F}, 728 Imm5 = {imm5,16#1F}, 729 Imm8 = {imm8,16#FF}, 730 Imm12 = {imm12,16#FFF}, 731 Imm16 = {imm16,16#FFFF}, 732 Imm24 = {imm24,16#FFFFF}, 733 Imm25 = {imm25,16#FFFFF1}, 734 %% 735 AM1_1 = {Imm8,Imm4}, 736 AM1_2 = Rm, 737 AM1_3_1 = {Rm,{'lsl',Imm5}}, 738 AM1_3_2 = {Rm,{'lsr',Imm5}}, 739 AM1_3_3 = {Rm,{'asr',Imm5}}, 740 AM1_3_4 = {Rm,{'ror',Imm5}}, 741 AM1_3_5 = {Rm,{'lsl',Rs}}, 742 AM1_3_6 = {Rm,{'lsr',Rs}}, 743 AM1_3_7 = {Rm,{'asr',Rs}}, 744 AM1_3_8 = {Rm,{'ror',Rs}}, 745 AM1_3_9 = {Rm,'rrx'}, 746 %% 747 AM2ShiftOp1 = {'lsl',Imm5}, 748 AM2ShiftOp2 = {'lsr',Imm5}, 749 AM2ShiftOp3 = {'asr',Imm5}, 750 AM2ShiftOp4 = {'ror',Imm5}, 751 AM2ShiftOp5 = 'rrx', 752 SignP = '+', 753 SignM = '-', 754 AM2_1_1 = {immediate_offset,Rn,SignP,Imm12}, 755 AM2_1_2 = {immediate_offset,Rn,SignM,Imm12}, 756 AM2_2_1 = {register_offset,Rn,SignP,Rm}, 757 AM2_2_2 = {register_offset,Rn,SignM,Rm}, 758 AM2_3_1 = {scaled_register_offset,Rn,SignP,Rm,AM2ShiftOp1}, 759 AM2_3_2 = {scaled_register_offset,Rn,SignM,Rm,AM2ShiftOp2}, 760 AM2_3_3 = {scaled_register_offset,Rn,SignP,Rm,AM2ShiftOp3}, 761 AM2_3_4 = {scaled_register_offset,Rn,SignM,Rm,AM2ShiftOp4}, 762 AM2_3_5 = {scaled_register_offset,Rn,SignP,Rm,AM2ShiftOp5}, 763 AM2_4_1 = {immediate_pre_indexed,Rn,SignP,Imm12}, 764 AM2_4_2 = {immediate_pre_indexed,Rn,SignM,Imm12}, 765 AM2_5_1 = {register_pre_indexed,Rn,SignP,Rm}, 766 AM2_5_2 = {register_pre_indexed,Rn,SignM,Rm}, 767 AM2_6_1 = {scaled_register_pre_indexed,Rn,SignP,Rm,AM2ShiftOp1}, 768 AM2_6_2 = {scaled_register_pre_indexed,Rn,SignM,Rm,AM2ShiftOp2}, 769 AM2_6_3 = {scaled_register_pre_indexed,Rn,SignP,Rm,AM2ShiftOp3}, 770 AM2_6_4 = {scaled_register_pre_indexed,Rn,SignM,Rm,AM2ShiftOp4}, 771 AM2_6_5 = {scaled_register_pre_indexed,Rn,SignP,Rm,AM2ShiftOp5}, 772 AM2_7_1 = {immediate_post_indexed,Rn,SignP,Imm12}, 773 AM2_7_2 = {immediate_post_indexed,Rn,SignM,Imm12}, 774 AM2_8_1 = {register_post_indexed,Rn,SignP,Rm}, 775 AM2_8_2 = {register_post_indexed,Rn,SignM,Rm}, 776 AM2_9_1 = {scaled_register_post_indexed,Rn,SignP,Rm,AM2ShiftOp1}, 777 AM2_9_2 = {scaled_register_post_indexed,Rn,SignM,Rm,AM2ShiftOp2}, 778 AM2_9_3 = {scaled_register_post_indexed,Rn,SignP,Rm,AM2ShiftOp3}, 779 AM2_9_4 = {scaled_register_post_indexed,Rn,SignM,Rm,AM2ShiftOp4}, 780 AM2_9_5 = {scaled_register_post_indexed,Rn,SignP,Rm,AM2ShiftOp5}, 781 %% 782 AM3_1_1 = {immediate_offset,Rn,SignP,Imm8}, 783 AM3_1_2 = {immediate_offset,Rn,SignM,Imm8}, 784 AM3_2_1 = {register_offset,Rn,SignP,Rm}, 785 AM3_2_2 = {register_offset,Rn,SignM,Rm}, 786 AM3_3_1 = {immediate_pre_indexed,Rn,SignP,Imm8}, 787 AM3_3_2 = {immediate_pre_indexed,Rn,SignM,Imm8}, 788 AM3_4_1 = {register_pre_indexed,Rn,SignP,Rm}, 789 AM3_4_2 = {register_pre_indexed,Rn,SignM,Rm}, 790 AM3_5_1 = {immediate_post_indexed,Rn,SignP,Imm8}, 791 AM3_5_2 = {immediate_post_indexed,Rn,SignM,Imm8}, 792 AM3_6_1 = {register_post_indexed,Rn,SignP,Rm}, 793 AM3_6_2 = {register_post_indexed,Rn,SignM,Rm}, 794 %% 795 AM4_1 = 'ia', 796 AM4_2 = 'ib', 797 AM4_3 = 'da', 798 AM4_4 = 'db', 799 AM4_5 = 'fa', 800 AM4_6 = 'fd', 801 AM4_7 = 'ea', 802 AM4_8 = 'ed', 803 %% 804 AM5_1_1 = {offset,Rn,SignP,Imm8}, 805 AM5_1_2 = {offset,Rn,SignM,Imm8}, 806 AM5_2_1 = {pre_indexed,Rn,SignP,Imm8}, 807 AM5_2_2 = {pre_indexed,Rn,SignM,Imm8}, 808 AM5_3_1 = {post_indexed,Rn,SignP,Imm8}, 809 AM5_3_2 = {post_indexed,Rn,SignM,Imm8}, 810 AM5_4 = {unindexed,Rn,Imm8}, 811 %% 812 Cond_eq = {'cond','eq'}, 813 Cond_ne = {'cond','ne'}, 814 Cond_cs = {'cond','cs'}, 815 Cond_hs = {'cond','hs'}, 816 Cond_cc = {'cond','cc'}, 817 Cond_lo = {'cond','lo'}, 818 Cond_mi = {'cond','mi'}, 819 Cond_pl = {'cond','pl'}, 820 Cond_vs = {'cond','vs'}, 821 Cond_vc = {'cond','vc'}, 822 Cond_hi = {'cond','hi'}, 823 Cond_ls = {'cond','ls'}, 824 Cond_ge = {'cond','ge'}, 825 Cond_lt = {'cond','lt'}, 826 Cond_gt = {'cond','gt'}, 827 Cond_le = {'cond','le'}, 828 Cond_al = {'cond','al'}, 829 %% 830 t(OS,'adc',{Cond_al,S0,Rd,Rn,AM1_1}), % test all AM1 operands 831 t(OS,'adc',{Cond_al,S0,Rd,Rn,AM1_2}), 832 t(OS,'adc',{Cond_al,S0,Rd,Rn,AM1_3_1}), 833 t(OS,'adc',{Cond_al,S0,Rd,Rn,AM1_3_2}), 834 t(OS,'adc',{Cond_al,S0,Rd,Rn,AM1_3_3}), 835 t(OS,'adc',{Cond_al,S0,Rd,Rn,AM1_3_4}), 836 t(OS,'adc',{Cond_al,S0,Rd,Rn,AM1_3_5}), 837 t(OS,'adc',{Cond_al,S0,Rd,Rn,AM1_3_6}), 838 t(OS,'adc',{Cond_al,S0,Rd,Rn,AM1_3_7}), 839 t(OS,'adc',{Cond_al,S0,Rd,Rn,AM1_3_8}), 840 t(OS,'adc',{Cond_al,S0,Rd,Rn,AM1_3_9}), 841 t(OS,'add',{Cond_al,S0,Rd,Rn,AM1_1}), % test all S operands 842 t(OS,'add',{Cond_al,S1,Rd,Rn,AM1_1}), 843 t(OS,'and',{Cond_eq,S0,Rd,Rn,AM1_1}), % test all Cond operands 844 t(OS,'and',{Cond_ne,S0,Rd,Rn,AM1_1}), 845 t(OS,'and',{Cond_cs,S0,Rd,Rn,AM1_1}), 846 t(OS,'and',{Cond_hs,S0,Rd,Rn,AM1_1}), 847 t(OS,'and',{Cond_cc,S0,Rd,Rn,AM1_1}), 848 t(OS,'and',{Cond_lo,S0,Rd,Rn,AM1_1}), 849 t(OS,'and',{Cond_mi,S0,Rd,Rn,AM1_1}), 850 t(OS,'and',{Cond_pl,S0,Rd,Rn,AM1_1}), 851 t(OS,'and',{Cond_vs,S0,Rd,Rn,AM1_1}), 852 t(OS,'and',{Cond_vc,S0,Rd,Rn,AM1_1}), 853 t(OS,'and',{Cond_hi,S0,Rd,Rn,AM1_1}), 854 t(OS,'and',{Cond_ls,S0,Rd,Rn,AM1_1}), 855 t(OS,'and',{Cond_ge,S0,Rd,Rn,AM1_1}), 856 t(OS,'and',{Cond_lt,S0,Rd,Rn,AM1_1}), 857 t(OS,'and',{Cond_gt,S0,Rd,Rn,AM1_1}), 858 t(OS,'and',{Cond_le,S0,Rd,Rn,AM1_1}), 859 t(OS,'and',{Cond_al,S0,Rd,Rn,AM1_1}), 860 t(OS,'b',{Cond_al,Imm24}), 861 t(OS,'bic',{Cond_al,S0,Rd,Rn,AM1_1}), 862 t(OS,'bkpt',{Imm16}), 863 t(OS,'bl',{Cond_al,Imm24}), 864 t(OS,'blx',{Imm25}), 865 t(OS,'blx',{Cond_al,Rm}), 866 t(OS,'bx',{Cond_al,Rm}), 867 t(OS,'cdp',{Cond_al,CpNum,CpOp4,CRd,CRn,CRm,CpOp3}), 868 t(OS,'cdp2',{CpNum,CpOp4,CRd,CRn,CRm,CpOp3}), 869 t(OS,'clz',{Cond_al,Rd,Rm}), 870 t(OS,'cmn',{Cond_al,Rn,AM1_1}), 871 t(OS,'cmp',{Cond_al,Rn,AM1_1}), 872 t(OS,'eor',{Cond_al,S0,Rd,Rn,AM1_1}), 873 t(OS,'ldc',{Cond_al,L0,CpNum,CRd,AM5_1_1}), % test all AM5 operands 874 t(OS,'ldc',{Cond_al,L1,CpNum,CRd,AM5_1_2}), 875 t(OS,'ldc',{Cond_al,L0,CpNum,CRd,AM5_2_1}), 876 t(OS,'ldc',{Cond_al,L1,CpNum,CRd,AM5_2_2}), 877 t(OS,'ldc',{Cond_al,L0,CpNum,CRd,AM5_3_1}), 878 t(OS,'ldc',{Cond_al,L1,CpNum,CRd,AM5_3_2}), 879 t(OS,'ldc',{Cond_al,L0,CpNum,CRd,AM5_4}), 880 t(OS,'ldc2',{L0,CpNum,CRd,AM5_1_1}), 881 t(OS,'ldm',{Cond_al,AM4_1,Rn,'!',Registers}), 882 t(OS,'ldm',{Cond_al,AM4_1,Rn,Registers}), % test all AM4 operands 883 t(OS,'ldm',{Cond_al,AM4_2,Rn,Registers}), % test all AM4 operands 884 t(OS,'ldm',{Cond_al,AM4_3,Rn,Registers}), % test all AM4 operands 885 t(OS,'ldm',{Cond_al,AM4_4,Rn,Registers}), % test all AM4 operands 886 t(OS,'ldm',{Cond_al,AM4_5,Rn,Registers}), % test all AM4 operands 887 t(OS,'ldm',{Cond_al,AM4_6,Rn,Registers}), % test all AM4 operands 888 t(OS,'ldm',{Cond_al,AM4_7,Rn,Registers}), % test all AM4 operands 889 t(OS,'ldm',{Cond_al,AM4_8,Rn,Registers}), % test all AM4 operands 890 t(OS,'ldr',{Cond_al,Rd,AM2_1_1}), % test all AM2 operands 891 t(OS,'ldr',{Cond_al,Rd,AM2_1_2}), 892 t(OS,'ldr',{Cond_al,Rd,AM2_2_1}), 893 t(OS,'ldr',{Cond_al,Rd,AM2_2_2}), 894 t(OS,'ldr',{Cond_al,Rd,AM2_3_1}), 895 t(OS,'ldr',{Cond_al,Rd,AM2_3_2}), 896 t(OS,'ldr',{Cond_al,Rd,AM2_3_3}), 897 t(OS,'ldr',{Cond_al,Rd,AM2_3_4}), 898 t(OS,'ldr',{Cond_al,Rd,AM2_3_5}), 899 t(OS,'ldr',{Cond_al,Rd,AM2_4_1}), 900 t(OS,'ldr',{Cond_al,Rd,AM2_4_2}), 901 t(OS,'ldr',{Cond_al,Rd,AM2_5_1}), 902 t(OS,'ldr',{Cond_al,Rd,AM2_5_2}), 903 t(OS,'ldr',{Cond_al,Rd,AM2_6_1}), 904 t(OS,'ldr',{Cond_al,Rd,AM2_6_2}), 905 t(OS,'ldr',{Cond_al,Rd,AM2_6_3}), 906 t(OS,'ldr',{Cond_al,Rd,AM2_6_4}), 907 t(OS,'ldr',{Cond_al,Rd,AM2_6_5}), 908 t(OS,'ldr',{Cond_al,Rd,AM2_7_1}), 909 t(OS,'ldr',{Cond_al,Rd,AM2_7_2}), 910 t(OS,'ldr',{Cond_al,Rd,AM2_8_1}), 911 t(OS,'ldr',{Cond_al,Rd,AM2_8_2}), 912 t(OS,'ldr',{Cond_al,Rd,AM2_9_1}), 913 t(OS,'ldr',{Cond_al,Rd,AM2_9_2}), 914 t(OS,'ldr',{Cond_al,Rd,AM2_9_3}), 915 t(OS,'ldr',{Cond_al,Rd,AM2_9_4}), 916 t(OS,'ldr',{Cond_al,Rd,AM2_9_5}), 917 t(OS,'ldrb',{Cond_al,Rd,AM2_1_1}), 918 t(OS,'ldrd',{Cond_al,Rd,AM3_1_1}), 919 t(OS,'ldrh',{Cond_al,Rd,AM3_1_1}), % test all AM3 operands 920 t(OS,'ldrh',{Cond_al,Rd,AM3_1_2}), 921 t(OS,'ldrh',{Cond_al,Rd,AM3_2_1}), 922 t(OS,'ldrh',{Cond_al,Rd,AM3_2_2}), 923 t(OS,'ldrh',{Cond_al,Rd,AM3_3_1}), 924 t(OS,'ldrh',{Cond_al,Rd,AM3_3_2}), 925 t(OS,'ldrh',{Cond_al,Rd,AM3_4_1}), 926 t(OS,'ldrh',{Cond_al,Rd,AM3_4_2}), 927 t(OS,'ldrh',{Cond_al,Rd,AM3_5_1}), 928 t(OS,'ldrh',{Cond_al,Rd,AM3_5_2}), 929 t(OS,'ldrh',{Cond_al,Rd,AM3_6_1}), 930 t(OS,'ldrh',{Cond_al,Rd,AM3_6_2}), 931 t(OS,'ldrsb',{Cond_al,Rd,AM3_1_1}), 932 t(OS,'ldrsh',{Cond_al,Rd,AM3_1_1}), 933 t(OS,'mcr',{Cond_al,CpNum,CpOp3,Rd,CRn,CRm,CpOp3}), 934 t(OS,'mcr2',{CpNum,CpOp3,Rd,CRn,CRm,CpOp3}), 935 t(OS,'mcrr',{Cond_al,CpNum,CpOp4,Rd,Rn,CRm}), 936 t(OS,'mla',{Cond_al,S0,Rd,Rm,Rs,Rn}), 937 t(OS,'mov',{Cond_al,S0,Rd,AM1_1}), 938 t(OS,'mrc',{Cond_al,CpNum,CpOp3,Rd,CRn,CRm,CpOp3}), 939 t(OS,'mrc2',{CpNum,CpOp3,Rd,CRn,CRm,CpOp3}), 940 t(OS,'mrrc',{Cond_al,CpNum,CpOp4,Rd,Rn,CRm}), 941 t(OS,'mrs',{Cond_al,Rd,'cpsr'}), 942 t(OS,'msr',{Cond_al,'cpsr',FieldMask4,Imm8,Imm4}), 943 t(OS,'msr',{Cond_al,'cpsr',FieldMask4,Rm}), 944 t(OS,'mul',{Cond_al,S0,Rd,Rm,Rs}), 945 t(OS,'mvn',{Cond_al,S1,Rd,AM1_1}), 946 t(OS,'orr',{Cond_al,S0,Rd,Rn,AM1_1}), 947 t(OS,'pld',{AM2_1_1}), 948 t(OS,'qadd',{Cond_al,Rd,Rm,Rn}), 949 t(OS,'qdadd',{Cond_al,Rd,Rm,Rn}), 950 t(OS,'qdsub',{Cond_al,Rd,Rm,Rn}), 951 t(OS,'qsub',{Cond_al,Rd,Rm,Rn}), 952 t(OS,'rsb',{Cond_al,S0,Rd,Rn,AM1_1}), 953 t(OS,'rsc',{Cond_al,S0,Rd,Rn,AM1_1}), 954 t(OS,'sbc',{Cond_al,S0,Rd,Rn,AM1_1}), 955 t(OS,'smla',{BT0,BT0,Cond_al,Rd,Rm,Rs,Rn}), 956 t(OS,'smla',{BT0,BT1,Cond_al,Rd,Rm,Rs,Rn}), 957 t(OS,'smla',{BT1,BT0,Cond_al,Rd,Rm,Rs,Rn}), 958 t(OS,'smla',{BT1,BT1,Cond_al,Rd,Rm,Rs,Rn}), 959 t(OS,'smlal',{Cond_al,S0,RdLo,RdHi,Rm,Rs}), 960 t(OS,'smlal',{BT0,BT1,Cond_al,RdLo,RdHi,Rm,Rs}), 961 t(OS,'smlaw',{BT1,Cond_al,Rd,Rm,Rs,Rn}), 962 t(OS,'smull',{Cond_al,S0,RdLo,RdHi,Rm,Rs}), 963 t(OS,'smul',{BT1,BT0,Cond_al,Rd,Rm,Rs}), 964 t(OS,'smulw',{BT1,Cond_al,Rd,Rm,Rs}), 965 t(OS,'stc',{Cond_al,L0,CpNum,CRd,AM5_1_1}), 966 t(OS,'stc2',{L0,CpNum,CRd,AM5_1_1}), 967 t(OS,'stm',{Cond_al,AM4_1,Rn,Registers}), 968 t(OS,'str',{Cond_al,Rd,AM2_1_1}), 969 t(OS,'strb',{Cond_al,Rd,AM2_1_1}), 970 t(OS,'strd',{Cond_al,Rd,AM3_1_1}), 971 t(OS,'strh',{Cond_al,Rd,AM3_1_1}), 972 t(OS,'sub',{Cond_al,S0,Rd,Rn,AM1_1}), 973 t(OS,'swi',{Cond_al,Imm24}), 974 t(OS,'swp',{Cond_al,Rd,Rm,Rn}), 975 t(OS,'swpb',{Cond_al,Rd,Rm,Rn}), 976 t(OS,'teq',{Cond_al,Rn,AM1_1}), 977 t(OS,'tst',{Cond_al,Rn,AM1_1}), 978 t(OS,'umlal',{Cond_al,S0,RdLo,RdHi,Rm,Rs}), 979 t(OS,'umull',{Cond_al,S0,RdLo,RdHi,Rm,Rs}), 980 []. 981 982dotest() -> dotest1(group_leader()). 983 984dotest(File) -> 985 {ok,OS} = file:open(File, [write]), 986 dotest1(OS), 987 file:close(OS). 988 989-endif. 990