* make m68k compile

git-svn-id: trunk@1138 -
This commit is contained in:
peter 2005-09-19 11:46:23 +00:00
parent d60f16c069
commit 1f8c074ab4
6 changed files with 649 additions and 751 deletions

1
.gitattributes vendored
View File

@ -192,6 +192,7 @@ compiler/m68k/r68ksri.inc svneol=native#text/plain
compiler/m68k/r68ksta.inc svneol=native#text/plain
compiler/m68k/r68kstd.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/rgcpu.pas svneol=native#text/plain
compiler/make_old.cmd -text

View File

@ -40,6 +40,7 @@ type
taicpu = class(tai_cpu_abstract)
opsize : topsize;
constructor op_none(op : tasmop);
constructor op_none(op : tasmop;_size : topsize);
constructor op_reg(op : tasmop;_size : topsize;_op1 : tregister);
@ -147,6 +148,13 @@ type
end;
constructor taicpu.op_none(op : tasmop);
begin
inherited create(op);
init(S_NO);
end;
constructor taicpu.op_none(op : tasmop;_size : topsize);
begin
inherited create(op);
@ -455,7 +463,7 @@ type
result:=operand_write;
end;
// fake
// internalerror(200404091);
end;

View File

@ -199,7 +199,7 @@ interface
end
else
getopstr:=getreferencestring(o.ref^);
top_reglist:
top_regset:
begin
hs:='';
for i:=RS_D0 to RS_D7 do

View File

@ -36,8 +36,15 @@ implementation
**************************************}
{$ifndef NOTARGETLINUX}
,t_linux,t_amiga
,t_linux
{$endif}
,t_amiga
{**************************************
Assembler Readers
**************************************}
,ra68kmot
{**************************************
Assemblers

363
compiler/m68k/ra68k.pas Executable file
View 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