+ Z80 internal asm: produce correct opcodes for register operands

git-svn-id: trunk@45250 -
This commit is contained in:
nickysn 2020-05-04 02:17:30 +00:00
parent 90ee079cd1
commit 256597be58

View File

@ -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;