mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-25 17:11:08 +02:00
* make m68k compile
git-svn-id: trunk@1138 -
This commit is contained in:
parent
d60f16c069
commit
1f8c074ab4
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -192,6 +192,7 @@ compiler/m68k/r68ksri.inc svneol=native#text/plain
|
|||||||
compiler/m68k/r68ksta.inc svneol=native#text/plain
|
compiler/m68k/r68ksta.inc svneol=native#text/plain
|
||||||
compiler/m68k/r68kstd.inc svneol=native#text/plain
|
compiler/m68k/r68kstd.inc svneol=native#text/plain
|
||||||
compiler/m68k/r68ksup.inc svneol=native#text/plain
|
compiler/m68k/r68ksup.inc svneol=native#text/plain
|
||||||
|
compiler/m68k/ra68k.pas svneol=native#text/plain
|
||||||
compiler/m68k/ra68kmot.pas svneol=native#text/plain
|
compiler/m68k/ra68kmot.pas svneol=native#text/plain
|
||||||
compiler/m68k/rgcpu.pas svneol=native#text/plain
|
compiler/m68k/rgcpu.pas svneol=native#text/plain
|
||||||
compiler/make_old.cmd -text
|
compiler/make_old.cmd -text
|
||||||
|
@ -40,6 +40,7 @@ type
|
|||||||
|
|
||||||
taicpu = class(tai_cpu_abstract)
|
taicpu = class(tai_cpu_abstract)
|
||||||
opsize : topsize;
|
opsize : topsize;
|
||||||
|
constructor op_none(op : tasmop);
|
||||||
constructor op_none(op : tasmop;_size : topsize);
|
constructor op_none(op : tasmop;_size : topsize);
|
||||||
|
|
||||||
constructor op_reg(op : tasmop;_size : topsize;_op1 : tregister);
|
constructor op_reg(op : tasmop;_size : topsize;_op1 : tregister);
|
||||||
@ -147,6 +148,13 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
constructor taicpu.op_none(op : tasmop);
|
||||||
|
begin
|
||||||
|
inherited create(op);
|
||||||
|
init(S_NO);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
constructor taicpu.op_none(op : tasmop;_size : topsize);
|
constructor taicpu.op_none(op : tasmop;_size : topsize);
|
||||||
begin
|
begin
|
||||||
inherited create(op);
|
inherited create(op);
|
||||||
@ -455,7 +463,7 @@ type
|
|||||||
result:=operand_write;
|
result:=operand_write;
|
||||||
end;
|
end;
|
||||||
// fake
|
// fake
|
||||||
|
|
||||||
// internalerror(200404091);
|
// internalerror(200404091);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ interface
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
getopstr:=getreferencestring(o.ref^);
|
getopstr:=getreferencestring(o.ref^);
|
||||||
top_reglist:
|
top_regset:
|
||||||
begin
|
begin
|
||||||
hs:='';
|
hs:='';
|
||||||
for i:=RS_D0 to RS_D7 do
|
for i:=RS_D0 to RS_D7 do
|
||||||
|
@ -36,8 +36,15 @@ implementation
|
|||||||
**************************************}
|
**************************************}
|
||||||
|
|
||||||
{$ifndef NOTARGETLINUX}
|
{$ifndef NOTARGETLINUX}
|
||||||
,t_linux,t_amiga
|
,t_linux
|
||||||
{$endif}
|
{$endif}
|
||||||
|
,t_amiga
|
||||||
|
|
||||||
|
{**************************************
|
||||||
|
Assembler Readers
|
||||||
|
**************************************}
|
||||||
|
|
||||||
|
,ra68kmot
|
||||||
|
|
||||||
{**************************************
|
{**************************************
|
||||||
Assemblers
|
Assemblers
|
||||||
|
363
compiler/m68k/ra68k.pas
Executable file
363
compiler/m68k/ra68k.pas
Executable file
@ -0,0 +1,363 @@
|
|||||||
|
{
|
||||||
|
Copyright (c) 1998-2003 by Carl Eric Codere and Peter Vreman
|
||||||
|
|
||||||
|
Handles the common 68k assembler reader routines
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
}
|
||||||
|
unit ra68k;
|
||||||
|
|
||||||
|
{$i fpcdefs.inc}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
aasmbase,aasmtai,aasmcpu,
|
||||||
|
cpubase,rautils,cclasses;
|
||||||
|
|
||||||
|
type
|
||||||
|
Tm68kOperand=class(TOperand)
|
||||||
|
end;
|
||||||
|
|
||||||
|
Tm68kInstruction=class(TInstruction)
|
||||||
|
opsize : topsize;
|
||||||
|
function ConcatInstruction(p : taasmoutput):tai;override;
|
||||||
|
function ConcatLabeledInstr(p : taasmoutput):tai;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
verbose,cgbase;
|
||||||
|
|
||||||
|
{*****************************************************************************
|
||||||
|
TM68kInstruction
|
||||||
|
*****************************************************************************}
|
||||||
|
|
||||||
|
function TM68kInstruction.ConcatInstruction(p : taasmoutput):tai;
|
||||||
|
var
|
||||||
|
fits : boolean;
|
||||||
|
begin
|
||||||
|
result:=nil;
|
||||||
|
fits := FALSE;
|
||||||
|
{ setup specific opcodetions for first pass }
|
||||||
|
|
||||||
|
{ Setup special operands }
|
||||||
|
{ Convert to general form as to conform to the m68k opcode table }
|
||||||
|
if (opcode = A_ADDA) or (opcode = A_ADDI)
|
||||||
|
then opcode := A_ADD
|
||||||
|
else
|
||||||
|
{ CMPM excluded because of GAS v1.34 BUG }
|
||||||
|
if (opcode = A_CMPA) or
|
||||||
|
(opcode = A_CMPI) then
|
||||||
|
opcode := A_CMP
|
||||||
|
else
|
||||||
|
if opcode = A_EORI then
|
||||||
|
opcode := A_EOR
|
||||||
|
else
|
||||||
|
if opcode = A_MOVEA then
|
||||||
|
opcode := A_MOVE
|
||||||
|
else
|
||||||
|
if opcode = A_ORI then
|
||||||
|
opcode := A_OR
|
||||||
|
else
|
||||||
|
if (opcode = A_SUBA) or (opcode = A_SUBI) then
|
||||||
|
opcode := A_SUB;
|
||||||
|
|
||||||
|
{ Setup operand types }
|
||||||
|
|
||||||
|
(*
|
||||||
|
in opcode <> A_MOVEM then
|
||||||
|
begin
|
||||||
|
|
||||||
|
while not(fits) do
|
||||||
|
begin
|
||||||
|
{ set the opcodetion cache, if the opcodetion }
|
||||||
|
{ occurs the first time }
|
||||||
|
if (it[i].i=opcode) and (ins_cache[opcode]=-1) then
|
||||||
|
ins_cache[opcode]:=i;
|
||||||
|
|
||||||
|
if (it[i].i=opcode) and (instr.ops=it[i].ops) then
|
||||||
|
begin
|
||||||
|
{ first fit }
|
||||||
|
case instr.ops of
|
||||||
|
0 : begin
|
||||||
|
fits:=true;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
1 :
|
||||||
|
begin
|
||||||
|
if (optyp1 and it[i].o1)<>0 then
|
||||||
|
begin
|
||||||
|
fits:=true;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
2 : if ((optyp1 and it[i].o1)<>0) and
|
||||||
|
((optyp2 and it[i].o2)<>0) then
|
||||||
|
begin
|
||||||
|
fits:=true;
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
3 : if ((optyp1 and it[i].o1)<>0) and
|
||||||
|
((optyp2 and it[i].o2)<>0) and
|
||||||
|
((optyp3 and it[i].o3)<>0) then
|
||||||
|
begin
|
||||||
|
fits:=true;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end; { end case }
|
||||||
|
end; { endif }
|
||||||
|
if it[i].i=A_NONE then
|
||||||
|
begin
|
||||||
|
{ NO MATCH! }
|
||||||
|
Message(asmr_e_invalid_combination_opcode_and_operand);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
inc(i);
|
||||||
|
end; { end while }
|
||||||
|
*)
|
||||||
|
fits:=TRUE;
|
||||||
|
|
||||||
|
{ We add the opcode to the opcode linked list }
|
||||||
|
if fits then
|
||||||
|
begin
|
||||||
|
case ops of
|
||||||
|
0:
|
||||||
|
if opsize <> S_NO then
|
||||||
|
result:=(taicpu.op_none(opcode,opsize))
|
||||||
|
else
|
||||||
|
result:=(taicpu.op_none(opcode,S_NO));
|
||||||
|
1: begin
|
||||||
|
case operands[1].opr.typ of
|
||||||
|
OPR_SYMBOL:
|
||||||
|
begin
|
||||||
|
result:=(taicpu.op_sym_ofs(opcode,
|
||||||
|
opsize, operands[1].opr.symbol,operands[1].opr.symofs));
|
||||||
|
end;
|
||||||
|
OPR_CONSTANT:
|
||||||
|
begin
|
||||||
|
result:=(taicpu.op_const(opcode,
|
||||||
|
opsize, operands[1].opr.val));
|
||||||
|
end;
|
||||||
|
OPR_REGISTER:
|
||||||
|
result:=(taicpu.op_reg(opcode,opsize,operands[1].opr.reg));
|
||||||
|
OPR_REFERENCE:
|
||||||
|
if opsize <> S_NO then
|
||||||
|
begin
|
||||||
|
result:=(taicpu.op_ref(opcode,
|
||||||
|
opsize,operands[1].opr.ref));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{ special jmp and call case with }
|
||||||
|
{ symbolic references. }
|
||||||
|
if opcode in [A_BSR,A_JMP,A_JSR,A_BRA,A_PEA] then
|
||||||
|
begin
|
||||||
|
result:=(taicpu.op_ref(opcode,
|
||||||
|
S_NO,operands[1].opr.ref));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
end;
|
||||||
|
OPR_NONE:
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
2: begin
|
||||||
|
{ source }
|
||||||
|
case operands[1].opr.typ of
|
||||||
|
{ reg,reg }
|
||||||
|
{ reg,ref }
|
||||||
|
OPR_REGISTER:
|
||||||
|
begin
|
||||||
|
case operands[2].opr.typ of
|
||||||
|
OPR_REGISTER:
|
||||||
|
begin
|
||||||
|
result:=(taicpu.op_reg_reg(opcode,
|
||||||
|
opsize,operands[1].opr.reg,operands[2].opr.reg));
|
||||||
|
end;
|
||||||
|
OPR_REFERENCE:
|
||||||
|
result:=(taicpu.op_reg_ref(opcode,
|
||||||
|
opsize,operands[1].opr.reg,operands[2].opr.ref));
|
||||||
|
else { else case }
|
||||||
|
begin
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
end;
|
||||||
|
end; { end second operand case for OPR_REGISTER }
|
||||||
|
end;
|
||||||
|
{ regset, ref }
|
||||||
|
OPR_regset:
|
||||||
|
begin
|
||||||
|
case operands[2].opr.typ of
|
||||||
|
OPR_REFERENCE :
|
||||||
|
result:=(taicpu.op_regset_ref(opcode,
|
||||||
|
opsize,operands[1].opr.regset,operands[2].opr.ref));
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
end;
|
||||||
|
end; { end second operand case for OPR_regset }
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ const,reg }
|
||||||
|
{ const,const }
|
||||||
|
{ const,ref }
|
||||||
|
OPR_CONSTANT:
|
||||||
|
case operands[2].opr.typ of
|
||||||
|
{ constant, constant does not have a specific size. }
|
||||||
|
OPR_CONSTANT:
|
||||||
|
result:=(taicpu.op_const_const(opcode,
|
||||||
|
S_NO,operands[1].opr.val,operands[2].opr.val));
|
||||||
|
OPR_REFERENCE:
|
||||||
|
begin
|
||||||
|
result:=(taicpu.op_const_ref(opcode,
|
||||||
|
opsize,operands[1].opr.val,
|
||||||
|
operands[2].opr.ref))
|
||||||
|
end;
|
||||||
|
OPR_REGISTER:
|
||||||
|
begin
|
||||||
|
result:=(taicpu.op_const_reg(opcode,
|
||||||
|
opsize,operands[1].opr.val,
|
||||||
|
operands[2].opr.reg))
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
end;
|
||||||
|
end; { end second operand case for OPR_CONSTANT }
|
||||||
|
{ ref,reg }
|
||||||
|
{ ref,ref }
|
||||||
|
OPR_REFERENCE:
|
||||||
|
case operands[2].opr.typ of
|
||||||
|
OPR_REGISTER:
|
||||||
|
begin
|
||||||
|
result:=(taicpu.op_ref_reg(opcode,
|
||||||
|
opsize,operands[1].opr.ref,
|
||||||
|
operands[2].opr.reg));
|
||||||
|
end;
|
||||||
|
OPR_regset:
|
||||||
|
begin
|
||||||
|
result:=(taicpu.op_ref_regset(opcode,
|
||||||
|
opsize,operands[1].opr.ref,
|
||||||
|
operands[2].opr.regset));
|
||||||
|
end;
|
||||||
|
OPR_REFERENCE: { special opcodes }
|
||||||
|
result:=(taicpu.op_ref_ref(opcode,
|
||||||
|
opsize,operands[1].opr.ref,
|
||||||
|
operands[2].opr.ref));
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
end;
|
||||||
|
end; { end second operand case for OPR_REFERENCE }
|
||||||
|
OPR_SYMBOL: case operands[2].opr.typ of
|
||||||
|
OPR_REFERENCE:
|
||||||
|
begin
|
||||||
|
result:=(taicpu.op_sym_ofs_ref(opcode,
|
||||||
|
opsize,operands[1].opr.symbol,operands[1].opr.symofs,
|
||||||
|
operands[2].opr.ref))
|
||||||
|
end;
|
||||||
|
OPR_REGISTER:
|
||||||
|
begin
|
||||||
|
result:=(taicpu.op_sym_ofs_reg(opcode,
|
||||||
|
opsize,operands[1].opr.symbol,operands[1].opr.symofs,
|
||||||
|
operands[2].opr.reg))
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
end;
|
||||||
|
end; { end second operand case for OPR_SYMBOL }
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
end;
|
||||||
|
end; { end first operand case }
|
||||||
|
end;
|
||||||
|
3: begin
|
||||||
|
if (opcode = A_DIVSL) or (opcode = A_DIVUL) or (opcode = A_MULU)
|
||||||
|
or (opcode = A_MULS) or (opcode = A_DIVS) or (opcode = A_DIVU) then
|
||||||
|
begin
|
||||||
|
if (operands[1].opr.typ <> OPR_REGISTER)
|
||||||
|
or (operands[2].opr.typ <> OPR_REGISTER)
|
||||||
|
or (operands[3].opr.typ <> OPR_REGISTER) then
|
||||||
|
begin
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
result:=(taicpu. op_reg_reg_reg(opcode,opsize,
|
||||||
|
operands[1].opr.reg,operands[2].opr.reg,operands[3].opr.reg));
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
end;
|
||||||
|
end; { end case }
|
||||||
|
end;
|
||||||
|
if assigned(result) then
|
||||||
|
p.concat(result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TM68kInstruction.ConcatLabeledInstr(p : taasmoutput):tai;
|
||||||
|
begin
|
||||||
|
if ((opcode >= A_BCC) and (opcode <= A_BVS)) or
|
||||||
|
(opcode = A_BRA) or (opcode = A_BSR) or
|
||||||
|
(opcode = A_JMP) or (opcode = A_JSR) or
|
||||||
|
((opcode >= A_FBEQ) and (opcode <= A_FBNGLE)) then
|
||||||
|
begin
|
||||||
|
if ops > 2 then
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand)
|
||||||
|
else if operands[1].opr.typ <> OPR_SYMBOL then
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand)
|
||||||
|
else if (operands[1].opr.typ = OPR_SYMBOL) and
|
||||||
|
(ops = 1) then
|
||||||
|
if assigned(operands[1].opr.symbol) and
|
||||||
|
(operands[1].opr.symofs=0) then
|
||||||
|
result:=taicpu.op_sym(opcode,S_NO,
|
||||||
|
operands[1].opr.symbol)
|
||||||
|
else
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
end
|
||||||
|
else if ((opcode >= A_DBCC) and (opcode <= A_DBF))
|
||||||
|
or ((opcode >= A_FDBEQ) and (opcode <= A_FDBNGLE)) then
|
||||||
|
begin
|
||||||
|
if (ops<>2) or
|
||||||
|
(operands[1].opr.typ <> OPR_REGISTER) or
|
||||||
|
(operands[2].opr.typ <> OPR_SYMBOL) or
|
||||||
|
(operands[2].opr.symofs <> 0) then
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand)
|
||||||
|
else
|
||||||
|
result:=taicpu.op_reg_sym(opcode,opsize,operands[1].opr.reg,
|
||||||
|
operands[2].opr.symbol);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Message(asmr_e_invalid_opcode_and_operand);
|
||||||
|
if assigned(result) then
|
||||||
|
p.concat(result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end.
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user