秋·风

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

【aarch64-win64】DonAlfredo已修复fpc将TSmallPoint赋值为一个负数,并将TSmallPoint赋值给TPoint时得到一个655xx的数值的bug

今天,DonAlfredo的修复方案经测试已修复将TSmallPoint赋值为一个负数,并将TSmallPoint赋值给TPoint时得到一个655xx的数值的bug。

image

修复过程:
打开fpcsrc\compiler\aarch64\cgcpu.pas
找到:procedure tcgaarch64.a_load_ref_reg_unaligned(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; register: tregister);
添加红色代码,修改后重新编译fpc及lazarus。
修复后解决了【aarch64-win64】修复aarch64 win64下lazarus不弹出SourceTabPopUpMenu及拖dock时出错的两个bug(2026-07-20更新) - 秋·风 - 博客园的bug

    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;

 

posted on 2026-07-25 20:48  秋·风  阅读(5)  评论(0)    收藏  举报