summaryrefslogtreecommitdiff
path: root/avx512-0037785/compiler/m68k/n68kcal.pas
blob: 1b614f82b3c53f14b3e1ded49d43e46906cf8aa5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
{
    Copyright (c) 2002 by Florian Klaempfl

    Implements the M68K specific part of call nodes

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

{$i fpcdefs.inc}

interface

    uses
      symdef,node,ncal,ncgcal;

    type
       tm68kcallnode = class(tcgcallnode)
        protected
         procedure gen_syscall_para(para: tcallparanode); override;
        public
         procedure do_syscall;override;
         procedure pop_parasize(pop_size: longint);override;
       end;


implementation

    uses
      globtype,systems,
      cutils,verbose,globals,
      symconst,symbase,symsym,symcpu,symtable,defutil,paramgr,parabase,
      cgbase,pass_2,
      cpuinfo,cpubase,aasmbase,aasmtai,aasmdata,aasmcpu,
      nmem,nld,ncnv,
      ncgutil,cgutils,cgobj,tgobj,rgobj,rgcpu,
      cg64f32,cgcpu,cpupi,procinfo;


    procedure tm68kcallnode.pop_parasize(pop_size: longint);
      begin
        if pop_size<>0 then
          current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_ADD,S_L,pop_size,NR_SP));
      end;


    procedure tm68kcallnode.gen_syscall_para(para: tcallparanode);
      begin
        { lib parameter has no special type but proccalloptions must be a syscall }
        para.left:=cloadnode.create(tcpuprocdef(procdefinition).libsym,tcpuprocdef(procdefinition).libsym.owner);
      end;


    procedure tm68kcallnode.do_syscall;
      var
        tmpref: treference;
      begin
        case target_info.system of
          system_m68k_atari:
            begin
              if po_syscall in tprocdef(procdefinition).procoptions then
                begin
                  reference_reset_base(tmpref,NR_SP,0,ctempposinvalid,2,[]);
                  tmpref.direction:=dir_dec;
                  current_asmdata.CurrAsmList.concat(taicpu.op_const_ref(A_MOVE,S_W,tprocdef(procdefinition).import_nr,tmpref));
                  current_asmdata.CurrAsmList.concat(taicpu.op_const(A_TRAP,S_NO,tprocdef(procdefinition).extnumber));
                  inc(pushedparasize,2); { kludge, trap code should be a hidden para instead... }
                end
              else
                internalerror(2016100302);
            end;
          system_m68k_amiga:
            begin
              if po_syscall_legacy in tprocdef(procdefinition).procoptions then
                begin
                  { according to Amiga Developer CD 2.1, system functions destroy the
                    scratch regs D0-D1 and A0-A1, but preserve all other regs. A6 is
                    not used as FP on Amiga any more (we use A5), so we don't need to
                    save it. (KB)
                    http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node0290.html }
                  reference_reset_base(tmpref,NR_A6,-tprocdef(procdefinition).extnumber,ctempposinvalid,4,[]);
                  current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_JSR,S_NO,tmpref));
                end
              else
                internalerror(2005010403);
            end;
          system_m68k_palmos:
            begin
              if po_syscall in tprocdef(procdefinition).procoptions then
                begin
                  if po_syscall_has_importnr in tprocdef(procdefinition).procoptions then
                    begin
                      cg.getcpuregister(current_asmdata.CurrAsmList,NR_D2);
                      current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_MOVE,S_L,tprocdef(procdefinition).import_nr,NR_D2));
                    end;
                  current_asmdata.CurrAsmList.concat(taicpu.op_const(A_TRAP,S_NO,15));
                  current_asmdata.CurrAsmList.concat(tai_const.create_16bit(tprocdef(procdefinition).extnumber));
                  if po_syscall_has_importnr in tprocdef(procdefinition).procoptions then
                    cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_D2);
                end
              else
                internalerror(2017081201);
            end;
          else
            internalerror(2004042901);
        end;
      end;


begin
   ccallnode:=tm68kcallnode;
end.