2 ### Class StubMOS: Create a MorphOS stub file #################################
11 my $class = ref($proto) || $proto;
12 my $self = $class->SUPER::new
( @_ );
13 bless ($self, $class);
20 $self->SUPER::header
(@_);
23 print "#include <emul/emulregs.h>\n";
24 print "#include <stdarg.h>\n";
31 my $prototype = $params{'prototype'};
33 if ($prototype->{type
} eq 'varargs') {
35 if ($prototype->{subtype
} ne 'tagcall') {
36 # We have to add the attribute to ourself first
38 $self->special_function_proto (@_);
39 print " __attribute__((varargs68k));\n";
41 $self->special_function_proto (@_);
45 $self->SUPER::function_proto
(@_);
52 my $prototype = $params{'prototype'};
53 my $sfd = $self->{SFD
};
55 if ($prototype->{type
} eq 'function') {
59 if (!$prototype->{nb
}) {
60 print " BASE_EXT_DECL\n";
63 elsif ($prototype->{type
} eq 'varargs') {
64 if ($prototype->{subtype
} ne 'tagcall') {
67 if ($prototype->{subtype
} eq 'printfcall') {
68 $na = $prototype->{numargs
} - 2;
71 # methodcall: first vararg is removed
72 $na = $prototype->{numargs
} - 3;
77 print " va_list _va;\n";
78 print " va_start (_va, $prototype->{___argnames}[$na]);\n";
79 print " return $$prototype{'real_funcname'}(BASE_PAR_NAME ";
82 # Shamelessly stolen from fd2inline ...
84 # number of regs that contain varargs
85 my $n = 9 - $prototype->{numregs
};
87 # add 4 bytes if that's an odd number, to avoid splitting a tag
88 my $d = $n & 1 ?
4 : 0;
90 # offset of the start of the taglist
93 # size of the stack frame
94 my $local = ($taglist + $n * 4 + $d + 8 + 15) & ~15;
98 # 0 - 3: next frame ptr
100 # 8 - 8+n*4+d+8-1: tag list start
101 # ? - local-1: padding
105 print " .globl $prototype->{funcname}\n";
106 print " .type $prototype->{funcname},\@function\n";
107 print "$prototype->{funcname}:\n";
108 print " stwu 1,-$local(1)\n";
110 printf " stw 0,%d(1)\n", $local + 4;
112 # If n is odd, one tag is split between regs and stack.
113 # Copy its ti_Data together with the ti_Tag.
117 printf " lwz 0,%d(1)\n", $local + 8;
122 for my $count ($prototype->{numregs
} .. 8) {
123 printf " stw %d,%d(1)\n",
125 ($count - $prototype->{numregs
}) * 4 + $taglist;
130 printf " stw 0,%d(1)\n", $taglist + $n * 4;
136 printf " addi 0,1,%d\n", $local + 8 + $d;
137 printf " stw 11,%d(1)\n", $taglist + $n * 4 + $d;
138 printf " stw 0,%d(1)\n", $taglist + $n * 4 + $d + 4;
140 # vararg_reg = &saved regs
142 printf " addi %d,1,%d\n",
143 $prototype->{numregs
} + 2, $taglist;
144 print " bl $prototype->{real_funcname}\n";
148 $self->SUPER::function_start
(@_);
155 my $prototype = $params{'prototype'};
156 my $argtype = $params{'argtype'};
157 my $argname = $params{'argname'};
158 my $argreg = $params{'argreg'};
159 my $argnum = $params{'argnum'};
160 my $sfd = $self->{SFD
};
162 if ($$prototype{'type'} eq 'function') {
163 print " REG_" . (uc $argreg) . " = (ULONG) $argname;\n";
165 elsif ($prototype->{type
} eq 'varargs') {
166 if ($prototype->{subtype
} eq 'tagcall') {
167 # if ($argnum < $prototype->{numargs} - 2) {
170 # if ($argreg =~ /^d[0-9]$/) {
171 # ( $regoffset = $argreg ) =~ s/^d//;
173 # elsif ($argreg =~ /^a[0-9]$/) {
174 # ( $regoffset = $argreg ) =~ s/^a//;
183 # # Save the non-varargs registers in the EmulHandle struct
185 # printf " stw %d,%d(2)\n", $argnum + 3, $regoffset;
188 elsif ($prototype->{subtype
} eq 'methodcall' &&
189 $argnum == $prototype->{numargs
} - 2) {
192 elsif ($argnum == $prototype->{numargs
} - 1) {
193 my $vt = $$prototype{'argtypes'}[$$prototype{'numargs'} - 1];
194 print ", ($vt) _va->overflow_arg_area";
197 $self->SUPER::function_arg
(@_);
201 $self->SUPER::function_arg
(@_);
208 my $prototype = $params{'prototype'};
209 my $sfd = $self->{SFD
};
212 if ($$prototype{'type'} eq 'function') {
213 if (!$prototype->{nb
}) {
214 print " REG_A6 = (ULONG) BASE_NAME;\n";
219 if (!$prototype->{nr
}) {
220 print "return ($prototype->{return}) ";
223 print "(*MyEmulHandle->EmulCallDirectOS)(-$prototype->{bias});\n";
226 elsif ($prototype->{type
} eq 'varargs') {
227 if ($prototype->{subtype
} eq 'tagcall') {
228 # number of regs that contain varargs
229 my $n = 9 - $prototype->{numregs
};
231 # add 4 bytes if that's an odd number, to avoid splitting a tag
232 my $d = $n & 1 ?
4 : 0;
234 # offset of the start of the taglist
237 # size of the stack frame
238 my $local = ($taglist + $n * 4 + $d + 8 + 15) & ~15;
240 # clear stack frame & return
241 printf " lwz 0,%d(1)\n", $local + 4;
243 printf " addi 1,1,%d\n", $local;
245 print ".L$prototype->{funcname}e1:\n";
246 print " .size $prototype->{funcname}," .
247 ".L$prototype->{funcname}e1-$prototype->{funcname}\n";
257 $self->SUPER::function_end
(@_);
262 sub special_function_proto
{
265 my $prototype = $params{'prototype'};
266 my $decl_regular = $params{'decl_regular'};
267 my $sfd = $self->{SFD
};
269 if ($prototype->{type
} eq 'varargs' && $decl_regular) {
270 my $rproto = $prototype->{real_prototype
};
272 print "$$rproto{'return'} $$rproto{'funcname'}(";
273 if (!$prototype->{nb
}) {
274 if ($$rproto{'numargs'} == 0) {
275 print "BASE_PAR_DECL0";
278 print "BASE_PAR_DECL ";
281 print join (', ', @
{$$rproto{'___args'}});
287 print "$$prototype{'return'}\n";
288 print "$$prototype{'funcname'}(";
289 if (!$prototype->{nb
}) {
290 if ($$prototype{'numargs'} == 0) {
291 print "BASE_PAR_DECL0";
294 print "BASE_PAR_DECL ";
300 for my $i (0 .. $#{@{$prototype->{___args}}}) {
301 if ($prototype->{subtype
} ne 'methodcall' ||
302 $i != $prototype->{numargs
} - 2 ) {
303 push @newargs, $prototype->{___args
}[$i];
307 print join (', ', @newargs);