2
Copyright (c) 1998-2001 by Florian Klaempfl and Pierre Muller
4
m68k family assembler instructions
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
****************************************************************************
29
cclasses,aasmtai,aasmdata,aasmsym,
30
aasmbase,globals,verbose,symtype,
31
cpubase,cpuinfo,cgbase,cgutils;
35
{ "mov reg,reg" source operand number }
37
{ "mov reg,reg" source operand number }
41
taicpu = class(tai_cpu_abstract_sym)
43
constructor op_none(op : tasmop);
44
constructor op_none(op : tasmop;_size : topsize);
46
constructor op_reg(op : tasmop;_size : topsize;_op1 : tregister);
47
constructor op_const(op : tasmop;_size : topsize;_op1 : longint);
48
constructor op_ref(op : tasmop;_size : topsize;_op1 : treference);
50
constructor op_reg_reg(op : tasmop;_size : topsize;_op1,_op2 : tregister);
51
constructor op_reg_ref(op : tasmop;_size : topsize;_op1 : tregister;_op2 : treference);
52
constructor op_reg_const(op:tasmop; _size: topsize; _op1: tregister; _op2: longint);
54
constructor op_const_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister);
55
constructor op_const_const(op : tasmop;_size : topsize;_op1,_op2 : longint);
56
constructor op_const_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : treference);
58
constructor op_ref_reg(op : tasmop;_size : topsize;_op1 : treference;_op2 : tregister);
59
{ this is only allowed if _op1 is an int value (_op1^.isintvalue=true) }
60
constructor op_ref_ref(op : tasmop;_size : topsize;_op1,_op2 : treference);
62
constructor op_reg_reg_reg(op : tasmop;_size : topsize;_op1,_op2,_op3 : tregister);
63
constructor op_const_reg_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : tregister);
64
constructor op_const_ref_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : treference;_op3 : tregister);
65
constructor op_reg_reg_ref(op : tasmop;_size : topsize;_op1,_op2 : tregister; _op3 : treference);
66
constructor op_const_reg_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : treference);
68
constructor op_reg_regset(op: tasmop; _size : topsize; _op1: tregister;const _op2: tcpuregisterset);
69
constructor op_regset_reg(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: tregister);
71
constructor op_ref_regset(op: tasmop; _size : topsize; _op1: treference;const _op2: tcpuregisterset);
72
constructor op_regset_ref(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: treference);
74
{ this is for Jmp instructions }
75
constructor op_cond_sym(op : tasmop;cond:TAsmCond;_size : topsize;_op1 : tasmsymbol);
77
constructor op_sym(op : tasmop;_size : topsize;_op1 : tasmsymbol);
79
constructor op_reg_sym(op: tasmop; _size : topsize; _op1: tregister; _op2 :tasmsymbol);
80
constructor op_sym_ofs_reg(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint;_op2 : tregister);
82
constructor op_sym_ofs(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint);
83
constructor op_sym_ofs_ref(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
85
function is_same_reg_move(regtype: Tregistertype):boolean;override;
86
function spilling_get_operation_type(opnr: longint): topertype;override;
89
procedure loadregset(opidx:longint;const s:tcpuregisterset);
90
procedure init(_size : topsize); { this need to be called by all constructor }
94
tai_align = class(tai_align_abstract)
101
function spilling_create_load(const ref:treference;r:tregister): tai;
102
function spilling_create_store(r:tregister; const ref:treference): tai;
110
{$WARNING FIX ME!! useful for debug, remove it, same table as in ag68kgas }
112
gas_op2str:op2strtable=
113
{ warning: CPU32 opcodes are not fully compatible with the MC68020. }
114
{ 68000 only opcodes }
116
'abcd','add','adda','addi','addq','addx','and','andi',
117
'asl','asr','bcc','bcs','beq','bge','bgt','bhi',
118
'ble','bls','blt','bmi','bne','bpl','bvc','bvs',
119
'bchg','bclr','bra','bset','bsr','btst','chk',
120
'clr','cmp','cmpa','cmpi','cmpm','dbcc','dbcs','dbeq','dbge',
121
'dbgt','dbhi','dble','dbls','dblt','dbmi','dbne','dbra',
122
'dbpl','dbt','dbvc','dbvs','dbf','divs','divu',
123
'eor','eori','exg','illegal','ext','jmp','jsr',
124
'lea','link','lsl','lsr','move','movea','movei','moveq',
125
'movem','movep','muls','mulu','nbcd','neg','negx',
126
'nop','not','or','ori','pea','rol','ror','roxl',
127
'roxr','rtr','rts','sbcd','scc','scs','seq','sge',
128
'sgt','shi','sle','sls','slt','smi','sne',
129
'spl','st','svc','svs','sf','sub','suba','subi','subq',
130
'subx','swap','tas','trap','trapv','tst','unlk',
131
'rte','reset','stop',
132
{ mc68010 instructions }
133
'bkpt','movec','moves','rtd',
134
{ mc68020 instructions }
135
'bfchg','bfclr','bfexts','bfextu','bfffo',
136
'bfins','bfset','bftst','callm','cas','cas2',
137
'chk2','cmp2','divsl','divul','extb','pack','rtm',
138
'trapcc','tracs','trapeq','trapf','trapge','trapgt',
139
'traphi','traple','trapls','traplt','trapmi','trapne',
140
'trappl','trapt','trapvc','trapvs','unpk',
141
{ fpu processor instructions - directly supported only. }
142
{ ieee aware and misc. condition codes not supported }
144
'fbeq','fbne','fbngt','fbgt','fbge','fbnge',
145
'fblt','fbnlt','fble','fbgl','fbngl','fbgle','fbngle',
146
'fdbeq','fdbne','fdbgt','fdbngt','fdbge','fdbnge',
147
'fdblt','fdbnlt','fdble','fdbgl','fdbngl','fdbgle','fdbngle',
148
'fseq','fsne','fsgt','fsngt','fsge','fsnge',
149
'fslt','fsnlt','fsle','fsgl','fsngl','fsgle','fsngle',
150
'fcmp','fdiv','fmove','fmovem',
151
'fmul','fneg','fnop','fsqrt','fsub','fsgldiv',
153
'ftrapeq','ftrapne','ftrapgt','ftrapngt','ftrapge','ftrapnge',
154
'ftraplt','ftrapnlt','ftraple','ftrapgl','ftrapngl','ftrapgle','ftrapngle',
155
{ protected instructions }
156
'cprestore','cpsave',
157
{ fpu unit protected instructions }
158
{ and 68030/68851 common mmu instructions }
159
{ (this may include 68040 mmu instructions) }
160
'frestore','fsave','pflush','pflusha','pload','pmove','ptest',
161
{ useful for assembly language output }
162
'label','db','s','b','fb');
165
{*****************************************************************************
167
*****************************************************************************}
171
procedure taicpu.loadregset(opidx:longint;const s:tcpuregisterset);
175
allocate_oper(opidx+1);
178
if typ<>top_regset then
183
for i:=RS_D0 to RS_D7 do
185
if assigned(add_reg_instruction_hook) and (i in regset^) then
186
add_reg_instruction_hook(self,newreg(R_INTREGISTER,i,R_SUBWHOLE));
188
for i:=RS_A0 to RS_SP do
190
if assigned(add_reg_instruction_hook) and (i in regset^) then
191
add_reg_instruction_hook(self,newreg(R_ADDRESSREGISTER,i,R_SUBWHOLE));
197
procedure taicpu.init(_size : topsize);
199
typ:=ait_instruction;
206
constructor taicpu.op_none(op : tasmop);
208
inherited create(op);
213
constructor taicpu.op_none(op : tasmop;_size : topsize);
215
inherited create(op);
220
constructor taicpu.op_reg(op : tasmop;_size : topsize;_op1 : tregister);
222
inherited create(op);
229
constructor taicpu.op_const(op : tasmop;_size : topsize;_op1 : longint);
231
inherited create(op);
234
loadconst(0,aword(_op1));
238
constructor taicpu.op_ref(op : tasmop;_size : topsize;_op1 : treference);
240
inherited create(op);
247
constructor taicpu.op_reg_reg(op : tasmop;_size : topsize;_op1,_op2 : tregister);
249
inherited create(op);
257
constructor taicpu.op_reg_const(op:tasmop; _size: topsize; _op1: tregister; _op2: longint);
259
inherited create(op);
263
loadconst(1,aword(_op2));
267
constructor taicpu.op_reg_ref(op : tasmop;_size : topsize;_op1 : tregister;_op2 : treference);
269
inherited create(op);
277
constructor taicpu.op_const_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister);
279
inherited create(op);
282
loadconst(0,aword(_op1));
287
constructor taicpu.op_const_const(op : tasmop;_size : topsize;_op1,_op2 : longint);
289
inherited create(op);
292
loadconst(0,aword(_op1));
293
loadconst(1,aword(_op2));
297
constructor taicpu.op_const_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : treference);
299
inherited create(op);
302
loadconst(0,aword(_op1));
307
constructor taicpu.op_ref_reg(op : tasmop;_size : topsize;_op1 : treference;_op2 : tregister);
309
inherited create(op);
317
constructor taicpu.op_ref_ref(op : tasmop;_size : topsize;_op1,_op2 : treference);
319
inherited create(op);
327
constructor taicpu.op_reg_reg_reg(op : tasmop;_size : topsize;_op1,_op2,_op3 : tregister);
329
inherited create(op);
337
constructor taicpu.op_const_reg_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : tregister);
339
inherited create(op);
342
loadconst(0,aword(_op1));
347
constructor taicpu.op_reg_reg_ref(op : tasmop;_size : topsize;_op1,_op2 : tregister;_op3 : treference);
349
inherited create(op);
358
constructor taicpu.op_const_ref_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : treference;_op3 : tregister);
360
inherited create(op);
363
loadconst(0,aword(_op1));
369
constructor taicpu.op_const_reg_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : treference);
371
inherited create(op);
374
loadconst(0,aword(_op1));
380
constructor taicpu.op_ref_regset(op: tasmop; _size : topsize; _op1: treference;const _op2: tcpuregisterset);
382
inherited create(op);
389
constructor taicpu.op_regset_ref(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: treference);
391
inherited create(op);
400
constructor taicpu.op_reg_regset(op: tasmop; _size : topsize; _op1: tregister;const _op2: tcpuregisterset);
402
inherited create(op);
410
constructor taicpu.op_regset_reg(op: tasmop; _size : topsize;const _op1: tcpuregisterset; _op2: tregister);
412
inherited create(op);
420
constructor taicpu.op_sym(op : tasmop;_size : topsize;_op1 : tasmsymbol);
422
inherited create(op);
425
loadsymbol(0,_op1,0);
429
constructor taicpu.op_reg_sym(op: tasmop; _size : topsize; _op1: tregister; _op2 :tasmsymbol);
431
inherited create(op);
435
loadsymbol(1,_op2,0);
439
constructor taicpu.op_sym_ofs_ref(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
441
inherited create(op);
444
loadsymbol(0,_op1,_op1ofs);
449
constructor taicpu.op_sym_ofs(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint);
451
inherited create(op);
454
loadsymbol(0,_op1,_op1ofs);
457
constructor taicpu.op_sym_ofs_reg(op : tasmop;_size : topsize;_op1 : tasmsymbol;_op1ofs:longint;_op2 : tregister);
459
inherited create(op);
462
if ((op >= A_DBCC) and (op <= A_DBF))
463
or ((op >= A_FDBEQ) and (op <= A_FDBNGLE)) then
466
loadsymbol(1,_op1,_op1ofs);
470
loadsymbol(0,_op1,_op1ofs);
476
constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_size : topsize;_op1 : tasmsymbol);
478
inherited create(op);
482
loadsymbol(0,_op1,0);
486
function taicpu.is_same_reg_move(regtype: Tregistertype):boolean;
488
result:=(((opcode=A_MOVE) or (opcode=A_EXG)) and
489
(regtype = R_INTREGISTER) and
491
(oper[0]^.typ=top_reg) and
492
(oper[1]^.typ=top_reg) and
493
(oper[0]^.reg=oper[1]^.reg)
495
(((opcode=A_MOVE) or (opcode=A_EXG) or (opcode=A_MOVEA)) and
496
(regtype = R_ADDRESSREGISTER) and
498
(oper[0]^.typ=top_reg) and
499
(oper[1]^.typ=top_reg) and
500
(oper[0]^.reg=oper[1]^.reg)
502
((opcode=A_FMOVE) and
503
(regtype = R_FPUREGISTER) and
505
(oper[0]^.typ=top_reg) and
506
(oper[1]^.typ=top_reg) and
507
(oper[0]^.reg=oper[1]^.reg)
512
function taicpu.spilling_get_operation_type(opnr: longint): topertype;
515
A_MOVE, A_MOVEQ, A_ADD, A_ADDQ, A_ADDX, A_SUB, A_SUBQ,
516
A_AND, A_LSR, A_LSL, A_ASR, A_ASL, A_EOR, A_EORI:
518
result:=operand_write;
520
result:=operand_read;
523
result:=operand_read;
525
result:=operand_write;
527
{$WARNING FIX ME!!! remove ugly debug code ... }
528
writeln('M68K: unknown opcode when spilling: ',gas_op2str[opcode]);
529
internalerror(200404091);
535
function spilling_create_load(const ref:treference;r:tregister): tai;
537
case getregtype(r) of
539
result:=taicpu.op_ref_reg(A_MOVE,S_L,ref,r);
541
result:=taicpu.op_ref_reg(A_MOVE,S_L,ref,r);
543
// no need to handle sizes here
544
result:=taicpu.op_ref_reg(A_FMOVE,S_FS,ref,r);
546
internalerror(200602011);
551
function spilling_create_store(r:tregister; const ref:treference): tai;
553
case getregtype(r) of
555
result:=taicpu.op_reg_ref(A_MOVE,S_L,r,ref);
557
result:=taicpu.op_reg_ref(A_MOVE,S_L,r,ref);
559
// no need to handle sizes here
560
result:=taicpu.op_reg_ref(A_FMOVE,S_FS,r,ref);
562
internalerror(200602012);