123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119openArch_declopenProgopenArm_declmoduletypeArm_input=sigvalcall_conv:(register,Arch_utils.empty,Arch_utils.empty,rflag,condt)calling_conventionendmoduleArm_core=structtypereg=registertyperegx=Arch_utils.emptytypexreg=Arch_utils.emptytypenonrecrflag=rflagtypecond=condttypeasm_op=Arm_instr_decl.arm_optypeextra_op=Arm_extra.arm_extra_optypelowering_options=Arm_lowering.lowering_optionsletatoI=X86_arch_full.atoIarm_declletasm_e=Arm_extra.arm_extraatoIletaparams=Arm_params.arm_paramsatoIletknown_implicits=["NF","_nf_";"ZF","_zf_";"CF","_cf_";"VF","_vf_"]letalloc_stack_need_extrasz=not(Arm_params_core.is_arith_small(Conv.cz_of_zsz))letis_ct_asm_op(o:asm_op)=matchowith|ARM_op((SDIV|UDIV),_)->false|_->trueletis_doit_asm_op(o:asm_op)=matchowith|ARM_op(ADC,_)->true|ARM_op(ADD,_)->true|ARM_op(ADR,_)->false(* Not DIT *)|ARM_op(AND,_)->true|ARM_op(ASR,_)->true|ARM_op(BFC,_)->true|ARM_op(BFI,_)->true|ARM_op(BIC,_)->true|ARM_op(CLZ,_)->true|ARM_op(CMN,_)->true|ARM_op(CMP,_)->true|ARM_op(EOR,_)->true|ARM_op(LDR,_)->true|ARM_op(LDRB,_)->true|ARM_op(LDRH,_)->true|ARM_op(LDRSB,_)->true|ARM_op(LDRSH,_)->true|ARM_op(LSL,_)->true|ARM_op(LSR,_)->true|ARM_op(MLA,_)->true|ARM_op(MLS,_)->true|ARM_op(MOV,_)->true|ARM_op(MOVT,_)->true|ARM_op(MUL,_)->true|ARM_op(MVN,_)->true|ARM_op(ORR,_)->true|ARM_op(REV,_)->true|ARM_op(REV16,_)->true|ARM_op(REVSH,_)->false(* Not DIT *)|ARM_op(ROR,_)->true|ARM_op(RSB,_)->false(* Not DIT *)|ARM_op(SBC,_)->true|ARM_op(SBFX,_)->true|ARM_op(SDIV,_)->false(* Not DIT *)|ARM_op(SMLA_hw_,_)->false(* Not DIT *)|ARM_op(SMLAL,_)->true|ARM_op(SMMUL,_)->false(* Not DIT *)|ARM_op(SMMULR,_)->false(* Not DIT *)|ARM_op(SMUL_hw_,_)->false(* Not DIT *)|ARM_op(SMULL,_)->true|ARM_op(SMULW_hw_,_)->false(* Not DIT *)|ARM_op(STR,_)->true|ARM_op(STRB,_)->true|ARM_op(STRH,_)->true|ARM_op(SUB,_)->true|ARM_op(TST,_)->true|ARM_op(UBFX,_)->true|ARM_op(UDIV,_)->false(* Not DIT *)|ARM_op(UMAAL,_)->false(* Not DIT *)|ARM_op(UMLAL,_)->true|ARM_op(UMULL,_)->true|ARM_op(UXTB,_)->true|ARM_op(UXTH,_)->true(* All of the extra ops compile into CT instructions (no DIV). *)letis_ct_asm_extra(_o:extra_op)=true(* All of the extra ops compile into DIT instructions only, but this needs to be checked manually. *)letis_doit_asm_extra(o:extra_op)=matchowith|Oarm_swap_->true|Oarm_add_large_imm->true|(Osmart_li_|Osmart_li_cc_)->true(* emit MOVT *)endmoduleArm(Lowering_params:Arm_input):Arch_full.Core_arch=structincludeArm_coreincludeLowering_params(* TODO_ARM: r9 is a platform register. (cf. arch_decl)
Here we assume it's just a variable register. *)letlowering_opt=()letnot_saved_stack=(Arm_params.arm_liparamsatoI).lip_not_saved_stackletpp_asm=Pp_arm_m4.print_progletcallstyle=Arch_full.ByReg{call=SomeLR;return=false}end