Kaynağa Gözat

+ Z80 internal asm: produce correct opcodes for register operands

git-svn-id: trunk@45250 -
nickysn 5 yıl önce
ebeveyn
işleme
256597be58
1 değiştirilmiş dosya ile 183 ekleme ve 8 silme
  1. 183 8
      compiler/z80/aasmcpu.pas

+ 183 - 8
compiler/z80/aasmcpu.pas

@@ -496,34 +496,209 @@ implementation
           InternalError(2020050403);
         end;
 
+      function EvalMaskCode(const maskcode: string): byte;
+        var
+          i: Integer;
+        begin
+          case maskcode of
+            'dd':
+              for i:=0 to insentry^.ops-1 do
+                if insentry^.optypes[i]=OT_REG16_BC_DE_HL_SP then
+                  begin
+                    if oper[i]^.typ<>top_reg then
+                      internalerror(2020050410);
+                    case oper[i]^.reg of
+                      NR_BC:
+                        result:=0;
+                      NR_DE:
+                        result:=1;
+                      NR_HL:
+                        result:=2;
+                      NR_SP:
+                        result:=3;
+                      else
+                        internalerror(2020050411);
+                    end;
+                  end;
+            'qq':
+              for i:=0 to insentry^.ops-1 do
+                if insentry^.optypes[i]=OT_REG16_BC_DE_HL_AF then
+                  begin
+                    if oper[i]^.typ<>top_reg then
+                      internalerror(2020050412);
+                    case oper[i]^.reg of
+                      NR_BC:
+                        result:=0;
+                      NR_DE:
+                        result:=1;
+                      NR_HL:
+                        result:=2;
+                      NR_AF:
+                        result:=3;
+                      else
+                        internalerror(2020050413);
+                    end;
+                  end;
+            'pp':
+              for i:=0 to insentry^.ops-1 do
+                if insentry^.optypes[i]=OT_REG16_BC_DE_IX_SP then
+                  begin
+                    if oper[i]^.typ<>top_reg then
+                      internalerror(2020050414);
+                    case oper[i]^.reg of
+                      NR_BC:
+                        result:=0;
+                      NR_DE:
+                        result:=1;
+                      NR_IX:
+                        result:=2;
+                      NR_SP:
+                        result:=3;
+                      else
+                        internalerror(2020050415);
+                    end;
+                  end;
+            'rr':
+              for i:=0 to insentry^.ops-1 do
+                if insentry^.optypes[i]=OT_REG16_BC_DE_IY_SP then
+                  begin
+                    if oper[i]^.typ<>top_reg then
+                      internalerror(2020050416);
+                    case oper[i]^.reg of
+                      NR_BC:
+                        result:=0;
+                      NR_DE:
+                        result:=1;
+                      NR_IY:
+                        result:=2;
+                      NR_SP:
+                        result:=3;
+                      else
+                        internalerror(2020050417);
+                    end;
+                  end;
+            'rrr':
+              for i:=0 to insentry^.ops-1 do
+                if insentry^.optypes[i]=OT_REG8 then
+                  begin
+                    if oper[i]^.typ<>top_reg then
+                      internalerror(2020050418);
+                    case oper[i]^.reg of
+                      NR_A:
+                        result:=7;
+                      NR_B:
+                        result:=0;
+                      NR_C:
+                        result:=1;
+                      NR_D:
+                        result:=2;
+                      NR_E:
+                        result:=3;
+                      NR_H:
+                        result:=4;
+                      NR_L:
+                        result:=5;
+                      else
+                        internalerror(2020050419);
+                    end;
+                  end;
+            'rrrRRR':
+              begin
+                if ops<>2 then
+                  internalerror(2020050420);
+                if (insentry^.optypes[0]<>OT_REG8) or (insentry^.optypes[1]<>OT_REG8) then
+                  internalerror(2020050421);
+                if (oper[0]^.typ<>top_reg) or (oper[1]^.typ<>top_reg) then
+                  internalerror(2020050422);
+                case oper[0]^.reg of
+                  NR_A:
+                    result:=7 shl 3;
+                  NR_B:
+                    result:=0 shl 3;
+                  NR_C:
+                    result:=1 shl 3;
+                  NR_D:
+                    result:=2 shl 3;
+                  NR_E:
+                    result:=3 shl 3;
+                  NR_H:
+                    result:=4 shl 3;
+                  NR_L:
+                    result:=5 shl 3;
+                  else
+                    internalerror(2020050419);
+                end;
+                case oper[1]^.reg of
+                  NR_A:
+                    result:=result or 7;
+                  NR_B:
+                    result:=result or 0;
+                  NR_C:
+                    result:=result or 1;
+                  NR_D:
+                    result:=result or 2;
+                  NR_E:
+                    result:=result or 3;
+                  NR_H:
+                    result:=result or 4;
+                  NR_L:
+                    result:=result or 5;
+                  else
+                    internalerror(2020050419);
+                end;
+              end;
+            else
+              internalerror(2020050409);
+          end;
+        end;
+
       procedure HandlePercent(token: string);
         var
-          bincodestr: string;
-          i, valcode: integer;
+          bincode: string;
+          maskcode: string;
+          i, valcode, shiftcount: integer;
           b: Byte;
         begin
-          bincodestr:='';
+          bincode:='';
+          maskcode:='';
           for i:=1 to length(token) do
             case token[i] of
               '%':
+                bincode:=bincode+'%';
+              '0':
                 begin
-                  bincodestr:=bincodestr+'%';
+                  bincode:=bincode+'0';
+                  maskcode:=maskcode+'0';
                 end;
-              '0','1':
+              '1':
                 begin
-                  bincodestr:=bincodestr+token[i];
+                  bincode:=bincode+'1';
+                  maskcode:=maskcode+'0';
                 end;
               'p','d','r','q':
                 begin
-                  bincodestr:=bincodestr+'0';
+                  bincode:=bincode+'0';
+                  maskcode:=maskcode+token[i];
                 end;
               '''':
                 begin
+                  if (maskcode='') or (maskcode[length(maskcode)]<>'r') then
+                    internalerror(2020050408);
+                  maskcode[length(maskcode)]:='R';
                 end;
               else
                 internalerror(2020050405);
             end;
-          Val(bincodestr,b,valcode);
+          Val(bincode,b,valcode);
+          while maskcode[1]='0' do
+            delete(maskcode,1,1);
+          shiftcount:=0;
+          while maskcode[length(maskcode)]='0' do
+            begin
+              delete(maskcode,length(maskcode),1);
+              Inc(shiftcount);
+            end;
+          b:=b or (EvalMaskCode(maskcode) shl shiftcount);
           objdata.writebytes(b,1);
         end;