瀏覽代碼

m68k: cleaned up and fixed cgcpu/fixref for coldfire at least; also enabled n68kmem node, so addressing with scaling is generated now

git-svn-id: trunk@28025 -
Károly Balogh 11 年之前
父節點
當前提交
519094055c
共有 2 個文件被更改,包括 54 次插入57 次删除
  1. 53 56
      compiler/m68k/cgcpu.pas
  2. 1 1
      compiler/m68k/cpunode.pas

+ 53 - 56
compiler/m68k/cgcpu.pas

@@ -448,6 +448,7 @@ unit cgcpu;
          hreg,idxreg : tregister;
          href : treference;
          instr : taicpu;
+         scale : aint;
        begin
          result:=false;
          { The MC68020+ has extended
@@ -565,76 +566,70 @@ unit cgcpu;
                  begin
                    if assigned(ref.symbol) then
                      begin
+                       //list.concat(tai_comment.create(strpnew('fixref: symbol')));
                        hreg:=cg.getaddressregister(list);
                        reference_reset_symbol(href,ref.symbol,ref.offset,ref.alignment);
                        list.concat(taicpu.op_ref_reg(A_LEA,S_L,href,hreg));
                        if ref.index<>NR_NO then
                          begin
+                           { fold the symbol + offset into the base, not the base into the index,
+                             because that might screw up the scalefactor of the reference }
+                           //list.concat(tai_comment.create(strpnew('fixref: symbol + offset (index + base)')));
                            idxreg:=getaddressregister(list);
-                           instr:=taicpu.op_reg_reg(A_MOVE,S_L,ref.base,idxreg);
-                           //add_move_instruction(instr);
-                           list.concat(instr);
-                           list.concat(taicpu.op_reg_reg(A_ADD,S_L,ref.index,idxreg));
-                           ref.index:=idxreg;
+                           reference_reset_base(href,ref.base,0,ref.alignment);
+                           href.index:=hreg;
+                           hreg:=getaddressregister(list);
+                           list.concat(taicpu.op_ref_reg(A_LEA,S_L,href,hreg));
+                           ref.base:=hreg;
                          end
                        else
-                         ref.index:=ref.base;
-                       ref.base:=hreg;
+                         ref.index:=hreg;
+
                        ref.offset:=0;
                        ref.symbol:=nil;
-                     end;
-                   { once the above is verified to work the below code can be
-                     removed }
-                   {if assigned(ref.symbol) and (ref.index=NR_NO) then
-                     begin
-                       hreg:=cg.getaddressregister(list);
-                       reference_reset_symbol(href,ref.symbol,0,ref.alignment);
-                       list.concat(taicpu.op_ref_reg(A_LEA,S_L,href,hreg));
-                       ref.index:=ref.base;
-                       ref.base:=hreg;
-                       ref.symbol:=nil;
-                     end;
-                   if (ref.index<>NR_NO) and assigned(ref.symbol) then
-                     begin
-                       hreg:=getaddressregister(list);
-                       list.concat(taicpu.op_reg_reg(A_MOVE,S_L,ref.base,hreg));
-                       list.concat(taicpu.op_reg_reg(A_ADD,S_L,ref.index,hreg));
-                       ref.base:=hreg;
-                       ref.index:=NR_NO;
-                     end;}
-                   {if (ref.index <> NR_NO) and assigned(ref.symbol) then
-                      internalerror(2002081403);}
-                   { base + reg }
-                   if ref.index <> NR_NO then
-                      begin
+                       fixref:=true;
+                     end
+                   else
+                     { base + reg }
+                     if ref.index <> NR_NO then
+                       begin
                          { base + reg + offset }
                          if (ref.offset < low(shortint)) or (ref.offset > high(shortint)) then
                            begin
-                              hreg:=getaddressregister(list);
-                              instr:=taicpu.op_reg_reg(A_MOVE,S_L,ref.base,hreg);
-                              //add_move_instruction(instr);
-                              list.concat(instr);
-                              list.concat(taicpu.op_const_reg(A_ADD,S_L,ref.offset,hreg));
-                              fixref:=true;
-                              ref.base:=hreg;
-                              ref.offset:=0;
-                              exit;
+                             hreg:=getaddressregister(list);
+                             if (ref.offset < low(smallint)) or (ref.offset > high(smallint)) then
+                               begin
+                                 instr:=taicpu.op_reg_reg(A_MOVE,S_L,ref.base,hreg);
+                                 //add_move_instruction(instr);
+                                 list.concat(instr);
+                                 list.concat(taicpu.op_const_reg(A_ADD,S_L,ref.offset,hreg));
+                               end
+                             else
+                               begin
+                                 //list.concat(tai_comment.create(strpnew('fixref: base + reg + offset lea')));
+                                 reference_reset_base(href,ref.base,ref.offset,ref.alignment);
+                                 list.concat(taicpu.op_ref_reg(A_LEA,S_NO,href,hreg));
+                               end;
+                             fixref:=true;
+                             ref.base:=hreg;
+                             ref.offset:=0;
+                             exit;
                            end;
-                      end
-                   else
-                   { base + offset }
-                   if (ref.offset < low(smallint)) or (ref.offset > high(smallint)) then
-                     begin
-                       hreg:=getaddressregister(list);
-                       instr:=taicpu.op_reg_reg(A_MOVE,S_L,ref.base,hreg);
-                       //add_move_instruction(instr);
-                       list.concat(instr);
-                       list.concat(taicpu.op_const_reg(A_ADD,S_L,ref.offset,hreg));
-                       fixref:=true;
-                       ref.offset:=0;
-                       ref.base:=hreg;
-                       exit;
-                     end;
+                       end
+                     else
+                       { base + offset }
+                       if (ref.offset < low(smallint)) or (ref.offset > high(smallint)) then
+                         begin
+                           hreg:=getaddressregister(list);
+                           instr:=taicpu.op_reg_reg(A_MOVE,S_L,ref.base,hreg);
+                           //add_move_instruction(instr);
+                           list.concat(instr);
+                           list.concat(taicpu.op_const_reg(A_ADD,S_L,ref.offset,hreg));
+                           fixref:=true;
+                           ref.offset:=0;
+                           ref.base:=hreg;
+                           exit;
+                         end;
                  end
                else
                  { Note: symbol -> ref would be supported as long as ref does not
@@ -644,10 +639,12 @@ unit cgcpu;
                    begin
                      hreg:=cg.getaddressregister(list);
                      idxreg:=ref.index;
+                     scale:=ref.scalefactor;
                      ref.index:=NR_NO;
                      list.concat(taicpu.op_ref_reg(A_LEA,S_L,ref,hreg));
                      reference_reset_base(ref,hreg,0,ref.alignment);
                      ref.index:=idxreg;
+                     ref.scalefactor:=scale;
                      fixref:=true;
                    end;
              end;

+ 1 - 1
compiler/m68k/cpunode.pas

@@ -38,7 +38,7 @@ unit cpunode;
          n68kcal,
 //       nppccon,
 //       nppcflw,
-//       n68kmem,
+         n68kmem,
 //       nppcset,
 //       nppcinl,
 //       nppcopt,