-
Notifications
You must be signed in to change notification settings - Fork 9
/
Stub68k.pl
129 lines (110 loc) · 3.6 KB
/
Stub68k.pl
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
127
128
129
### Class Stub68k: Create a 68k stub file #####################################
BEGIN {
package Stub68k;
use vars qw(@ISA);
@ISA = qw( Stub );
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = $class->SUPER::new( @_ );
bless ($self, $class);
return $self;
}
sub function_start {
my $self = shift;
my %params = @_;
my $prototype = $params{'prototype'};
my $sfd = $self->{SFD};
if ($prototype->{type} eq 'function') {
print "\n";
print "{\n";
if (!$prototype->{nb}) {
print " BASE_EXT_DECL\n";
}
if (!$prototype->{nr}) {
my $rettype_prefix = $prototype->{return};
my $rettype_postfix = "";
if ($prototype->{return} =~ /(.*\(\*+)(\).*)/) {
$rettype_prefix = $1;
$rettype_postfix = $2;
}
print " register $rettype_prefix _res $rettype_postfix __asm(\"d0\");\n";
}
if (!$prototype->{nb}) {
print " register $sfd->{basetype} _base __asm(\"a6\") " .
"= BASE_NAME;\n";
}
}
else {
$self->SUPER::function_start (@_);
}
}
sub function_arg {
my $self = shift;
my %params = @_;
my $prototype = $params{'prototype'};
my $argtype = $params{'argtype'};
my $argname = $params{'argname'};
my $argreg = $params{'argreg'};
my $argnum = $params{'argnum'};
my $sfd = $self->{SFD};
if ($$prototype{'type'} eq 'function') {
if ($argreg eq 'a4' || $argreg eq 'a5') {
$argreg = 'd7';
}
print " register $prototype->{args}[$argnum] __asm(\"$argreg\") " .
"= $argname;\n";
}
else {
$self->SUPER::function_arg (@_);
}
}
sub function_end {
my $self = shift;
my %params = @_;
my $prototype = $params{'prototype'};
my $sfd = $self->{SFD};
if ($$prototype{'type'} eq 'function') {
my $regs = join(',', @{$$prototype{'regs'}});
my $a4 = $regs =~ /a4/;
my $a5 = $regs =~ /a5/;
if ($a4 && $a5 && !$quiet) {
print STDERR "$$prototype{'funcname'} uses both a4 and a5 " .
"for arguments. This is not going to work.\n";
}
if ($a4) {
print " __asm volatile (\"exg d7,a4\\n\\tjsr a6@(-" .
"$prototype->{bias}:W)\\n\\texg d7,a4\"\n";
}
elsif ($a5) {
print " __asm volatile (\"exg d7,a5\\n\\tjsr a6@(-" .
"$prototype->{bias}:W)\\n\\texg d7,a5\"\n";
}
else {
print " __asm volatile (\"jsr a6@(-$prototype->{bias}:W)\"\n";
}
print " : " .
($prototype->{nr} ? "/* No output */" : '"=r" (_res)') . "\n";
print " : ";
if (!$prototype->{nb}) {
print '"r" (_base)';
}
for my $i (0 .. $prototype->{numargs} - 1) {
if ($i != 0 || !$prototype->{nb}) {
print ", ";
}
print '"r" (' . $prototype->{argnames}[$i] . ')';
}
print "\n";
print ' : "d0", "d1", "a0", "a1", "fp0", "fp1", "cc", "memory");';
print "\n";
if (!$prototype->{nr}) {
print " return _res;\n";
}
print "}\n";
}
else {
$self->SUPER::function_end (@_);
}
}
}