2
$Id: cpubase.pas,v 1.28 2004/05/06 22:01:54 florian Exp $
3
Copyright (c) 1998-2002 by Florian Klaempfl
5
Contains the base types for the m68k
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
****************************************************************************
23
{ This Unit contains the base types for the m68k
32
strings,cutils,cclasses,aasmbase,cpuinfo,cgbase;
34
{*****************************************************************************
36
*****************************************************************************}
39
{ warning: CPU32 opcodes are not fully compatible with the MC68020. }
40
{ 68000 only opcodes }
42
a_add,a_adda,a_addi,a_addq,a_addx,a_and,a_andi,
43
a_asl,a_asr,a_bcc,a_bcs,a_beq,a_bge,a_bgt,a_bhi,
44
a_ble,a_bls,a_blt,a_bmi,a_bne,a_bpl,a_bvc,a_bvs,
45
a_bchg,a_bclr,a_bra,a_bset,a_bsr,a_btst,a_chk,
46
a_clr,a_cmp,a_cmpa,a_cmpi,a_cmpm,a_dbcc,a_dbcs,a_dbeq,a_dbge,
47
a_dbgt,a_dbhi,a_dble,a_dbls,a_dblt,a_dbmi,a_dbne,a_dbra,
48
a_dbpl,a_dbt,a_dbvc,a_dbvs,a_dbf,a_divs,a_divu,
49
a_eor,a_eori,a_exg,a_illegal,a_ext,a_jmp,a_jsr,
50
a_lea,a_link,a_lsl,a_lsr,a_move,a_movea,a_movei,a_moveq,
51
a_movem,a_movep,a_muls,a_mulu,a_nbcd,a_neg,a_negx,
52
a_nop,a_not,a_or,a_ori,a_pea,a_rol,a_ror,a_roxl,
53
a_roxr,a_rtr,a_rts,a_sbcd,a_scc,a_scs,a_seq,a_sge,
54
a_sgt,a_shi,a_sle,a_sls,a_slt,a_smi,a_sne,
55
a_spl,a_st,a_svc,a_svs,a_sf,a_sub,a_suba,a_subi,a_subq,
56
a_subx,a_swap,a_tas,a_trap,a_trapv,a_tst,a_unlk,
58
{ mc68010 instructions }
59
a_bkpt,a_movec,a_moves,a_rtd,
60
{ mc68020 instructions }
61
a_bfchg,a_bfclr,a_bfexts,a_bfextu,a_bfffo,
62
a_bfins,a_bfset,a_bftst,a_callm,a_cas,a_cas2,
63
a_chk2,a_cmp2,a_divsl,a_divul,a_extb,a_pack,a_rtm,
64
a_trapcc,a_tracs,a_trapeq,a_trapf,a_trapge,a_trapgt,
65
a_traphi,a_traple,a_trapls,a_traplt,a_trapmi,a_trapne,
66
a_trappl,a_trapt,a_trapvc,a_trapvs,a_unpk,
67
{ fpu processor instructions - directly supported only. }
68
{ ieee aware and misc. condition codes not supported }
70
a_fbeq,a_fbne,a_fbngt,a_fbgt,a_fbge,a_fbnge,
71
a_fblt,a_fbnlt,a_fble,a_fbgl,a_fbngl,a_fbgle,a_fbngle,
72
a_fdbeq,a_fdbne,a_fdbgt,a_fdbngt,a_fdbge,a_fdbnge,
73
a_fdblt,a_fdbnlt,a_fdble,a_fdbgl,a_fdbngl,a_fdbgle,a_fdbngle,
74
a_fseq,a_fsne,a_fsgt,a_fsngt,a_fsge,a_fsnge,
75
a_fslt,a_fsnlt,a_fsle,a_fsgl,a_fsngl,a_fsgle,a_fsngle,
76
a_fcmp,a_fdiv,a_fmove,a_fmovem,
77
a_fmul,a_fneg,a_fnop,a_fsqrt,a_fsub,a_fsgldiv,
79
a_ftrapeq,a_ftrapne,a_ftrapgt,a_ftrapngt,a_ftrapge,a_ftrapnge,
80
a_ftraplt,a_ftrapnlt,a_ftraple,a_ftrapgl,a_ftrapngl,a_ftrapgle,a_ftrapngle,
81
{ protected instructions }
83
{ fpu unit protected instructions }
84
{ and 68030/68851 common mmu instructions }
85
{ (this may include 68040 mmu instructions) }
86
a_frestore,a_fsave,a_pflush,a_pflusha,a_pload,a_pmove,a_ptest,
87
{ useful for assembly language output }
88
a_label,a_none,a_dbxx,a_sxx,a_bxx,a_fbxx);
90
{# This should define the array of instructions as string }
91
op2strtable=array[tasmop] of string[11];
94
{# First value of opcode enumeration }
95
firstop = low(tasmop);
96
{# Last value of opcode enumeration }
97
lastop = high(tasmop);
99
{*****************************************************************************
101
*****************************************************************************}
104
{ Number of registers used for indexing in tables }
105
tregisterindex=0..{$i r68knor.inc}-1;
108
{ Available Superregisters }
112
R_SUBWHOLE = R_SUBNONE;
114
{ Available Registers }
117
{ Integer Super registers first and last }
118
first_int_imreg = RS_D7+1;
120
{ Float Super register first and last }
121
first_fpu_imreg = RS_FP7+1;
123
{ Integer Super registers first and last }
124
first_addr_imreg = RS_SP+1;
126
{ MM Super register first and last }
130
regnumber_count_bsstart = 64;
132
regnumber_table : array[tregisterindex] of tregister = (
136
regstabs_table : array[tregisterindex] of shortint = (
140
{ registers which may be destroyed by calls }
141
VOLATILE_INTREGISTERS = [];
142
VOLATILE_FPUREGISTERS = [];
145
totherregisterset = set of tregisterindex;
148
{*****************************************************************************
150
*****************************************************************************}
154
C_CC,C_LS,C_CS,C_LT,C_EQ,C_MI,C_F,C_NE,
155
C_GE,C_PL,C_GT,C_T,C_HI,C_VC,C_LE,C_VS
160
cond2str:array[TAsmCond] of string[3]=('',
161
'cc','ls','cs','lt','eq','mi','f','ne',
162
'ge','pl','gt','t','hi','vc','le','vs'
166
{*****************************************************************************
168
*****************************************************************************}
173
F_G,F_L,F_GE,F_LE,F_C,F_NC,F_A,F_AE,F_B,F_BE);
175
{*****************************************************************************
177
*****************************************************************************}
180
trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
182
{ direction of address register : }
184
tdirection = (dir_none,dir_inc,dir_dec);
187
preference = ^treference;
188
treference = packed record
194
{ symbol the symbol of this reference is relative to, nil if none }
195
relsymbol : tasmsymbol;
196
{ reference type addr or symbol itself }
198
options : trefoptions;
199
{ indexed increment and decrement mode }
201
direction : tdirection;
205
pparareference = ^tparareference;
206
tparareference = record
212
{*****************************************************************************
214
*****************************************************************************}
217
{ tparamlocation describes where a parameter for a procedure is stored.
218
References are given from the caller's point of view. The usual
219
TLocation isn't used, because contains a lot of unnessary fields.
221
tparalocation = record
227
LOC_REFERENCE : (reference : tparareference);
228
{ segment in reference at the same place as in loc_register }
229
LOC_REGISTER,LOC_CREGISTER : (
231
1 : (register,registerhigh : tregister);
232
{ overlay a registerlow }
233
2 : (registerlow : tregister);
234
{ overlay a 64 Bit register type }
235
3 : (reg64 : tregister64);
236
4 : (register64 : tregister64);
244
LOC_FLAGS : (resflags : tresflags);
248
{ can't do this, this layout depends on the host cpu. Use }
249
{ lo(valueqword)/hi(valueqword) instead (JM) }
250
{ 2 : (valuelow, valuehigh:AWord); }
251
{ overlay a complete 64 Bit value }
252
3 : (valueqword : qword);
255
LOC_REFERENCE : (reference : treference);
256
{ segment in reference at the same place as in loc_register }
257
LOC_REGISTER,LOC_CREGISTER : (
259
1 : (register,registerhigh,segment : tregister);
260
{ overlay a registerlow }
261
2 : (registerlow : tregister);
262
{ overlay a 64 Bit register type }
263
3 : (reg64 : tregister64);
264
4 : (register64 : tregister64);
269
{*****************************************************************************
271
*****************************************************************************}
273
{ S_NO = No Size of operand }
274
{ S_B = 8-bit size operand }
275
{ S_W = 16-bit size operand }
276
{ S_L = 32-bit size operand }
277
{ Floating point types }
278
{ S_FS = single type (32 bit) }
279
{ S_FD = double/64bit integer }
280
{ S_FX = Extended type }
281
topsize = (S_NO,S_B,S_W,S_L,S_FS,S_FD,S_FX,S_IQ);
283
{*****************************************************************************
285
*****************************************************************************}
288
{# maximum number of operands in assembler instruction }
291
{*****************************************************************************
292
Default generic sizes
293
*****************************************************************************}
295
{# Defines the default address size for a processor, }
297
{# the natural int size for a processor, }
299
{# the maximum float size for a processor, }
301
{# the size of a vector register for a processor }
305
{*****************************************************************************
307
*****************************************************************************}
309
{# Register indexes for stabs information, when some
310
parameters or variables are stored in registers.
312
Taken from m68kelf.h (DBX_REGISTER_NUMBER)
313
from GCC 3.x source code.
315
This is not compatible with the m68k-sun
318
stab_regindex : array[tregisterindex] of shortint =
323
{*****************************************************************************
324
Generic Register names
325
*****************************************************************************}
327
{# Stack pointer register }
328
NR_STACK_POINTER_REG = NR_SP;
329
RS_STACK_POINTER_REG = RS_SP;
330
{# Frame pointer register }
331
NR_FRAME_POINTER_REG = NR_A6;
332
RS_FRAME_POINTER_REG = RS_A6;
333
{# Register for addressing absolute data in a position independant way,
334
such as in PIC code. The exact meaning is ABI specific. For
335
further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
337
NR_PIC_OFFSET_REG = NR_A5;
338
{ Results are returned in this register (32-bit values) }
339
NR_FUNCTION_RETURN_REG = NR_D0;
340
RS_FUNCTION_RETURN_REG = NR_D0;
341
{ Low part of 64bit return value }
342
NR_FUNCTION_RETURN64_LOW_REG = NR_D0;
343
RS_FUNCTION_RETURN64_LOW_REG = RS_D0;
344
{ High part of 64bit return value }
345
NR_FUNCTION_RETURN64_HIGH_REG = NR_D1;
346
RS_FUNCTION_RETURN64_HIGH_REG = RS_D1;
347
{ The value returned from a function is available in this register }
348
NR_FUNCTION_RESULT_REG = NR_FUNCTION_RETURN_REG;
349
RS_FUNCTION_RESULT_REG = RS_FUNCTION_RETURN_REG;
350
{ The lowh part of 64bit value returned from a function }
351
NR_FUNCTION_RESULT64_LOW_REG = NR_FUNCTION_RETURN64_LOW_REG;
352
RS_FUNCTION_RESULT64_LOW_REG = RS_FUNCTION_RETURN64_LOW_REG;
353
{ The high part of 64bit value returned from a function }
354
NR_FUNCTION_RESULT64_HIGH_REG = NR_FUNCTION_RETURN64_HIGH_REG;
355
RS_FUNCTION_RESULT64_HIGH_REG = RS_FUNCTION_RETURN64_HIGH_REG;
357
{# Floating point results will be placed into this register }
358
NR_FPU_RESULT_REG = NR_FP0;
360
{*****************************************************************************
361
GCC /ABI linking information
362
*****************************************************************************}
364
{# Registers which must be saved when calling a routine declared as
365
cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
366
saved should be the ones as defined in the target ABI and / or GCC.
368
This value can be deduced from CALLED_USED_REGISTERS array in the
371
std_saved_intregisters = [RS_D2..RS_D7];
372
std_saved_addrregisters = [RS_A2..RS_A5];
373
{# Required parameter alignment when calling a routine declared as
374
stdcall and cdecl. The alignment value should be the one defined
375
by GCC or the target ABI.
377
The value of this constant is equal to the constant
378
PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
380
std_param_align = 4; { for 32-bit version only }
382
{*****************************************************************************
383
CPU Dependent Constants
384
*****************************************************************************}
387
{*****************************************************************************
389
*****************************************************************************}
391
function is_calljmp(o:tasmop):boolean;
393
procedure inverse_flags(var r : TResFlags);
394
function flags_to_cond(const f: TResFlags) : TAsmCond;
395
function cgsize2subreg(s:Tcgsize):Tsubregister;
397
function findreg_by_number(r:Tregister):tregisterindex;
398
function std_regnum_search(const s:string):Tregister;
399
function std_regname(r:Tregister):string;
401
function isaddressregister(reg : tregister) : boolean;
411
std_regname_table : array[tregisterindex] of string[7] = (
415
regnumber_index : array[tregisterindex] of tregisterindex = (
419
std_regname_index : array[tregisterindex] of tregisterindex = (
424
{*****************************************************************************
426
*****************************************************************************}
428
function is_calljmp(o:tasmop):boolean;
431
if o in [A_BXX,A_FBXX,A_DBXX,A_BCC..A_BVS,A_DBCC..A_DBVS,A_FBEQ..A_FSNGLE,
432
A_JSR,A_BSR,A_JMP] then
437
procedure inverse_flags(var r: TResFlags);
438
const flagsinvers : array[F_E..F_BE] of tresflags =
451
function flags_to_cond(const f: TResFlags) : TAsmCond;
452
const flags2cond: array[tresflags] of tasmcond = (
454
C_NE,{F_NE not equal}
457
C_GE,{F_GE ge signed}
458
C_LE,{F_LE le signed}
460
C_CC,{F_NC carry clear}
461
C_HI,{F_A gt unsigned}
462
C_CC,{F_AE ge unsigned}
463
C_CS,{F_B lt unsigned}
464
C_LS);{F_BE le unsigned}
466
flags_to_cond := flags2cond[f];
469
function cgsize2subreg(s:Tcgsize):Tsubregister;
473
cgsize2subreg:=R_SUBL;
475
cgsize2subreg:=R_SUBW;
477
cgsize2subreg:=R_SUBD;
479
internalerror(200301231);
484
function findreg_by_number(r:Tregister):tregisterindex;
486
result:=findreg_by_number_table(r,regnumber_index);
490
function std_regnum_search(const s:string):Tregister;
492
result:=regnumber_table[findreg_by_name_table(s,std_regname_table,std_regname_index)];
496
function std_regname(r:Tregister):string;
500
p:=findreg_by_number_table(r,regnumber_index);
502
result:=std_regname_table[p]
504
result:=generic_regname(r);
508
function isaddressregister(reg : tregister) : boolean;
510
result:=getregtype(reg)=R_ADDRESSREGISTER;
516
$Log: cpubase.pas,v $
517
Revision 1.28 2004/05/06 22:01:54 florian
518
* register numbers for address registers fixed
520
Revision 1.27 2004/05/06 20:30:51 florian
521
* m68k compiler compilation fixed
523
Revision 1.26 2004/04/25 21:26:16 florian
524
* some m68k stuff fixed
526
Revision 1.25 2004/04/18 21:13:59 florian
527
* more adaptions for m68k
529
Revision 1.24 2004/01/30 12:17:18 florian
530
* fixed some m68k compilation problems
532
Revision 1.23 2003/08/17 16:59:20 jonas
533
* fixed regvars so they work with newra (at least for ppc)
534
* fixed some volatile register bugs
535
+ -dnotranslation option for -dnewra, which causes the registers not to
536
be translated from virtual to normal registers. Requires support in
537
the assembler writer as well, which is only implemented in aggas/
540
Revision 1.22 2003/06/17 16:34:44 jonas
541
* lots of newra fixes (need getfuncretparaloc implementation for i386)!
542
* renamed all_intregisters to volatile_intregisters and made it
545
Revision 1.21 2003/06/03 13:01:59 daniel
546
* Register allocator finished
548
Revision 1.20 2003/04/23 13:40:33 peter
551
Revision 1.19 2003/04/23 12:35:35 florian
552
* fixed several issues with powerpc
553
+ applied a patch from Jonas for nested function calls (PowerPC only)
556
Revision 1.18 2003/02/19 22:00:16 daniel
557
* Code generator converted to new register notation
558
- Horribily outdated todo.txt removed
560
Revision 1.17 2003/02/02 19:25:54 carl
561
* Several bugfixes for m68k target (register alloc., opcode emission)
563
+ Generic add more complete (still not verified)
565
Revision 1.16 2003/01/09 15:49:56 daniel
566
* Added register conversion
568
Revision 1.15 2003/01/08 18:43:57 daniel
569
* Tregister changed into a record
571
Revision 1.14 2002/11/30 23:33:03 carl
572
* merges from Pierre's fixes in m68k fixes branch
574
Revision 1.13 2002/11/17 18:26:16 mazen
575
* fixed a compilation bug accmulator-->accumulator, in definition of return_result_reg
577
Revision 1.12 2002/11/17 17:49:09 mazen
578
+ return_result_reg and function_result_reg are now used, in all plateforms, to pass functions result between called function and its caller. See the explanation of each one
580
Revision 1.11 2002/10/14 16:32:36 carl
581
+ flag_2_cond implemented
583
Revision 1.10 2002/08/18 09:02:12 florian
584
* fixed compilation problems
586
Revision 1.9 2002/08/15 08:13:54 carl
587
- a_load_sym_ofs_reg removed
588
* loadvmt now calls loadaddr_ref_reg instead
590
Revision 1.8 2002/08/14 18:41:47 jonas
591
- remove valuelow/valuehigh fields from tlocation, because they depend
592
on the endianess of the host operating system -> difficult to get
593
right. Use lo/hi(location.valueqword) instead (remember to use
594
valueqword and not value!!)
596
Revision 1.7 2002/08/13 21:40:58 florian
597
* more fixes for ppc calling conventions
599
Revision 1.6 2002/08/13 18:58:54 carl
600
+ m68k problems with cvs fixed?()!
602
Revision 1.4 2002/08/12 15:08:44 carl
603
+ stab register indexes for powerpc (moved from gdb to cpubase)
604
+ tprocessor enumeration moved to cpuinfo
605
+ linker in target_info is now a class
606
* many many updates for m68k (will soon start to compile)
607
- removed some ifdef or correct them for correct cpu
609
Revision 1.3 2002/07/29 17:51:32 carl
610
+ restart m68k support