


























procedure tcgaarch64.a_load_ref_reg_unaligned(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; register: tregister); var href: treference; hreg1, hreg2, tmpreg,tmpreg2: tregister; i : Integer; begin case fromsize of OS_64,OS_S64: begin { split into two 32 bit loads } hreg1:=getintregister(list,OS_32); hreg2:=getintregister(list,OS_32); if target_info.endian=endian_big then begin tmpreg:=hreg1; hreg1:=hreg2; hreg2:=tmpreg; end; { can we use LDP? } if (ref.alignment=4) and (simple_ref_type(A_LDP,OS_32,PF_None,ref)=sr_simple) then list.concat(taicpu.op_reg_reg_ref(A_LDP,hreg1,hreg2,ref)) else begin a_load_ref_reg(list,OS_32,OS_32,ref,hreg1); href:=ref; inc(href.offset,4); a_load_ref_reg(list,OS_32,OS_32,href,hreg2); end; a_load_reg_reg(list,OS_32,OS_64,hreg1,register); list.concat(taicpu.op_reg_reg_const_const(A_BFI,register,makeregsize(hreg2,OS_64),32,32)); end; OS_16,OS_S16, OS_32,OS_S32: begin if ref.alignment=2 then begin href:=ref; if target_info.endian=endian_big then inc(href.offset,tcgsize2size[fromsize]-2); tmpreg:=getintregister(list,OS_32); a_load_ref_reg(list,OS_16,OS_32,href,tmpreg); tmpreg2:=getintregister(list,OS_32); for i:=1 to (tcgsize2size[fromsize]-1) div 2 do begin if target_info.endian=endian_big then dec(href.offset,2) else inc(href.offset,2); a_load_ref_reg(list,OS_16,OS_32,href,tmpreg2); list.concat(taicpu.op_reg_reg_const_const(A_BFI,tmpreg,tmpreg2,i*16,16)); end; a_load_reg_reg(list,fromsize,tosize,tmpreg,register); end else begin href:=ref; if target_info.endian=endian_big then inc(href.offset,tcgsize2size[fromsize]-1); tmpreg:=getintregister(list,OS_32); a_load_ref_reg(list,OS_8,OS_32,href,tmpreg); tmpreg2:=getintregister(list,OS_32); for i:=1 to tcgsize2size[fromsize]-1 do begin if target_info.endian=endian_big then dec(href.offset) else inc(href.offset); a_load_ref_reg(list,OS_8,OS_32,href,tmpreg2); list.concat(taicpu.op_reg_reg_const_const(A_BFI,tmpreg,tmpreg2,i*8,8)); end; if target_info.system=system_aarch64_win64 then begin { FIX: Check fromsize (or signedness) to decide sign extension } if (fromsize in [OS_S8, OS_S16]) or (tosize in [OS_S8, OS_S16]) then begin if (fromsize = OS_S8) then list.concat(taicpu.op_reg_reg(A_SXTB,tmpreg,tmpreg)) else list.concat(taicpu.op_reg_reg(A_SXTH,tmpreg,tmpreg)); end; end else if (tosize in [OS_S8,OS_S16]) then list.concat(taicpu.op_reg_reg(A_SXTH,tmpreg,tmpreg)); a_load_reg_reg(list,fromsize,tosize,tmpreg,register); end; end; else inherited; end; end;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。