1*0Sstevel@tonic-gate#!/usr/local/bin/perl
2*0Sstevel@tonic-gate
3*0Sstevel@tonic-gatepackage x86unix;
4*0Sstevel@tonic-gate
5*0Sstevel@tonic-gate$label="L000";
6*0Sstevel@tonic-gate$const="";
7*0Sstevel@tonic-gate$constl=0;
8*0Sstevel@tonic-gate
9*0Sstevel@tonic-gate$align=($main'aout)?"4":"16";
10*0Sstevel@tonic-gate$under=($main'aout)?"_":"";
11*0Sstevel@tonic-gate$com_start=($main'sol)?"/":"#";
12*0Sstevel@tonic-gate
13*0Sstevel@tonic-gatesub main'asm_init_output { @out=(); }
14*0Sstevel@tonic-gatesub main'asm_get_output { return(@out); }
15*0Sstevel@tonic-gatesub main'get_labels { return(@labels); }
16*0Sstevel@tonic-gatesub main'external_label { push(@labels,@_); }
17*0Sstevel@tonic-gate
18*0Sstevel@tonic-gateif ($main'cpp)
19*0Sstevel@tonic-gate	{
20*0Sstevel@tonic-gate	$align="ALIGN";
21*0Sstevel@tonic-gate	$under="";
22*0Sstevel@tonic-gate	$com_start='/*';
23*0Sstevel@tonic-gate	$com_end='*/';
24*0Sstevel@tonic-gate	}
25*0Sstevel@tonic-gate
26*0Sstevel@tonic-gate%lb=(	'eax',	'%al',
27*0Sstevel@tonic-gate	'ebx',	'%bl',
28*0Sstevel@tonic-gate	'ecx',	'%cl',
29*0Sstevel@tonic-gate	'edx',	'%dl',
30*0Sstevel@tonic-gate	'ax',	'%al',
31*0Sstevel@tonic-gate	'bx',	'%bl',
32*0Sstevel@tonic-gate	'cx',	'%cl',
33*0Sstevel@tonic-gate	'dx',	'%dl',
34*0Sstevel@tonic-gate	);
35*0Sstevel@tonic-gate
36*0Sstevel@tonic-gate%hb=(	'eax',	'%ah',
37*0Sstevel@tonic-gate	'ebx',	'%bh',
38*0Sstevel@tonic-gate	'ecx',	'%ch',
39*0Sstevel@tonic-gate	'edx',	'%dh',
40*0Sstevel@tonic-gate	'ax',	'%ah',
41*0Sstevel@tonic-gate	'bx',	'%bh',
42*0Sstevel@tonic-gate	'cx',	'%ch',
43*0Sstevel@tonic-gate	'dx',	'%dh',
44*0Sstevel@tonic-gate	);
45*0Sstevel@tonic-gate
46*0Sstevel@tonic-gate%regs=(	'eax',	'%eax',
47*0Sstevel@tonic-gate	'ebx',	'%ebx',
48*0Sstevel@tonic-gate	'ecx',	'%ecx',
49*0Sstevel@tonic-gate	'edx',	'%edx',
50*0Sstevel@tonic-gate	'esi',	'%esi',
51*0Sstevel@tonic-gate	'edi',	'%edi',
52*0Sstevel@tonic-gate	'ebp',	'%ebp',
53*0Sstevel@tonic-gate	'esp',	'%esp',
54*0Sstevel@tonic-gate	);
55*0Sstevel@tonic-gate
56*0Sstevel@tonic-gate%reg_val=(
57*0Sstevel@tonic-gate	'eax',	0x00,
58*0Sstevel@tonic-gate	'ebx',	0x03,
59*0Sstevel@tonic-gate	'ecx',	0x01,
60*0Sstevel@tonic-gate	'edx',	0x02,
61*0Sstevel@tonic-gate	'esi',	0x06,
62*0Sstevel@tonic-gate	'edi',	0x07,
63*0Sstevel@tonic-gate	'ebp',	0x05,
64*0Sstevel@tonic-gate	'esp',	0x04,
65*0Sstevel@tonic-gate	);
66*0Sstevel@tonic-gate
67*0Sstevel@tonic-gatesub main'LB
68*0Sstevel@tonic-gate	{
69*0Sstevel@tonic-gate	(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
70*0Sstevel@tonic-gate	return($lb{$_[0]});
71*0Sstevel@tonic-gate	}
72*0Sstevel@tonic-gate
73*0Sstevel@tonic-gatesub main'HB
74*0Sstevel@tonic-gate	{
75*0Sstevel@tonic-gate	(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
76*0Sstevel@tonic-gate	return($hb{$_[0]});
77*0Sstevel@tonic-gate	}
78*0Sstevel@tonic-gate
79*0Sstevel@tonic-gatesub main'DWP
80*0Sstevel@tonic-gate	{
81*0Sstevel@tonic-gate	local($addr,$reg1,$reg2,$idx)=@_;
82*0Sstevel@tonic-gate
83*0Sstevel@tonic-gate	$ret="";
84*0Sstevel@tonic-gate	$addr =~ s/(^|[+ \t])([A-Za-z_]+[A-Za-z0-9_]+)($|[+ \t])/$1$under$2$3/;
85*0Sstevel@tonic-gate	$reg1="$regs{$reg1}" if defined($regs{$reg1});
86*0Sstevel@tonic-gate	$reg2="$regs{$reg2}" if defined($regs{$reg2});
87*0Sstevel@tonic-gate	$ret.=$addr if ($addr ne "") && ($addr ne 0);
88*0Sstevel@tonic-gate	if ($reg2 ne "")
89*0Sstevel@tonic-gate		{
90*0Sstevel@tonic-gate		if($idx ne "" && $idx != 0)
91*0Sstevel@tonic-gate		    { $ret.="($reg1,$reg2,$idx)"; }
92*0Sstevel@tonic-gate		else
93*0Sstevel@tonic-gate		    { $ret.="($reg1,$reg2)"; }
94*0Sstevel@tonic-gate	        }
95*0Sstevel@tonic-gate	elsif ($reg1 ne "")
96*0Sstevel@tonic-gate		{ $ret.="($reg1)" }
97*0Sstevel@tonic-gate	return($ret);
98*0Sstevel@tonic-gate	}
99*0Sstevel@tonic-gate
100*0Sstevel@tonic-gatesub main'BP
101*0Sstevel@tonic-gate	{
102*0Sstevel@tonic-gate	return(&main'DWP(@_));
103*0Sstevel@tonic-gate	}
104*0Sstevel@tonic-gate
105*0Sstevel@tonic-gatesub main'BC
106*0Sstevel@tonic-gate	{
107*0Sstevel@tonic-gate	return @_;
108*0Sstevel@tonic-gate	}
109*0Sstevel@tonic-gate
110*0Sstevel@tonic-gatesub main'DWC
111*0Sstevel@tonic-gate	{
112*0Sstevel@tonic-gate	return @_;
113*0Sstevel@tonic-gate	}
114*0Sstevel@tonic-gate
115*0Sstevel@tonic-gate#sub main'BP
116*0Sstevel@tonic-gate#	{
117*0Sstevel@tonic-gate#	local($addr,$reg1,$reg2,$idx)=@_;
118*0Sstevel@tonic-gate#
119*0Sstevel@tonic-gate#	$ret="";
120*0Sstevel@tonic-gate#
121*0Sstevel@tonic-gate#	$addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
122*0Sstevel@tonic-gate#	$reg1="$regs{$reg1}" if defined($regs{$reg1});
123*0Sstevel@tonic-gate#	$reg2="$regs{$reg2}" if defined($regs{$reg2});
124*0Sstevel@tonic-gate#	$ret.=$addr if ($addr ne "") && ($addr ne 0);
125*0Sstevel@tonic-gate#	if ($reg2 ne "")
126*0Sstevel@tonic-gate#		{ $ret.="($reg1,$reg2,$idx)"; }
127*0Sstevel@tonic-gate#	else
128*0Sstevel@tonic-gate#		{ $ret.="($reg1)" }
129*0Sstevel@tonic-gate#	return($ret);
130*0Sstevel@tonic-gate#	}
131*0Sstevel@tonic-gate
132*0Sstevel@tonic-gatesub main'mov	{ &out2("movl",@_); }
133*0Sstevel@tonic-gatesub main'movb	{ &out2("movb",@_); }
134*0Sstevel@tonic-gatesub main'and	{ &out2("andl",@_); }
135*0Sstevel@tonic-gatesub main'or	{ &out2("orl",@_); }
136*0Sstevel@tonic-gatesub main'shl	{ &out2("sall",@_); }
137*0Sstevel@tonic-gatesub main'shr	{ &out2("shrl",@_); }
138*0Sstevel@tonic-gatesub main'xor	{ &out2("xorl",@_); }
139*0Sstevel@tonic-gatesub main'xorb	{ &out2("xorb",@_); }
140*0Sstevel@tonic-gatesub main'add	{ &out2("addl",@_); }
141*0Sstevel@tonic-gatesub main'adc	{ &out2("adcl",@_); }
142*0Sstevel@tonic-gatesub main'sub	{ &out2("subl",@_); }
143*0Sstevel@tonic-gatesub main'rotl	{ &out2("roll",@_); }
144*0Sstevel@tonic-gatesub main'rotr	{ &out2("rorl",@_); }
145*0Sstevel@tonic-gatesub main'exch	{ &out2("xchg",@_); }
146*0Sstevel@tonic-gatesub main'cmp	{ &out2("cmpl",@_); }
147*0Sstevel@tonic-gatesub main'lea	{ &out2("leal",@_); }
148*0Sstevel@tonic-gatesub main'mul	{ &out1("mull",@_); }
149*0Sstevel@tonic-gatesub main'div	{ &out1("divl",@_); }
150*0Sstevel@tonic-gatesub main'jmp	{ &out1("jmp",@_); }
151*0Sstevel@tonic-gatesub main'jmp_ptr { &out1p("jmp",@_); }
152*0Sstevel@tonic-gatesub main'je	{ &out1("je",@_); }
153*0Sstevel@tonic-gatesub main'jle	{ &out1("jle",@_); }
154*0Sstevel@tonic-gatesub main'jne	{ &out1("jne",@_); }
155*0Sstevel@tonic-gatesub main'jnz	{ &out1("jnz",@_); }
156*0Sstevel@tonic-gatesub main'jz	{ &out1("jz",@_); }
157*0Sstevel@tonic-gatesub main'jge	{ &out1("jge",@_); }
158*0Sstevel@tonic-gatesub main'jl	{ &out1("jl",@_); }
159*0Sstevel@tonic-gatesub main'ja	{ &out1("ja",@_); }
160*0Sstevel@tonic-gatesub main'jae	{ &out1("jae",@_); }
161*0Sstevel@tonic-gatesub main'jb	{ &out1("jb",@_); }
162*0Sstevel@tonic-gatesub main'jbe	{ &out1("jbe",@_); }
163*0Sstevel@tonic-gatesub main'jc	{ &out1("jc",@_); }
164*0Sstevel@tonic-gatesub main'jnc	{ &out1("jnc",@_); }
165*0Sstevel@tonic-gatesub main'jno	{ &out1("jno",@_); }
166*0Sstevel@tonic-gatesub main'dec	{ &out1("decl",@_); }
167*0Sstevel@tonic-gatesub main'inc	{ &out1("incl",@_); }
168*0Sstevel@tonic-gatesub main'push	{ &out1("pushl",@_); $stack+=4; }
169*0Sstevel@tonic-gatesub main'pop	{ &out1("popl",@_); $stack-=4; }
170*0Sstevel@tonic-gatesub main'pushf	{ &out0("pushf"); $stack+=4; }
171*0Sstevel@tonic-gatesub main'popf	{ &out0("popf"); $stack-=4; }
172*0Sstevel@tonic-gatesub main'not	{ &out1("notl",@_); }
173*0Sstevel@tonic-gatesub main'call	{ &out1("call",($_[0]=~/^\.L/?'':$under).$_[0]); }
174*0Sstevel@tonic-gatesub main'ret	{ &out0("ret"); }
175*0Sstevel@tonic-gatesub main'nop	{ &out0("nop"); }
176*0Sstevel@tonic-gate
177*0Sstevel@tonic-gate# The bswapl instruction is new for the 486. Emulate if i386.
178*0Sstevel@tonic-gatesub main'bswap
179*0Sstevel@tonic-gate	{
180*0Sstevel@tonic-gate	if ($main'i386)
181*0Sstevel@tonic-gate		{
182*0Sstevel@tonic-gate		&main'comment("bswapl @_");
183*0Sstevel@tonic-gate		&main'exch(main'HB(@_),main'LB(@_));
184*0Sstevel@tonic-gate		&main'rotr(@_,16);
185*0Sstevel@tonic-gate		&main'exch(main'HB(@_),main'LB(@_));
186*0Sstevel@tonic-gate		}
187*0Sstevel@tonic-gate	else
188*0Sstevel@tonic-gate		{
189*0Sstevel@tonic-gate		&out1("bswapl",@_);
190*0Sstevel@tonic-gate		}
191*0Sstevel@tonic-gate	}
192*0Sstevel@tonic-gate
193*0Sstevel@tonic-gatesub out2
194*0Sstevel@tonic-gate	{
195*0Sstevel@tonic-gate	local($name,$p1,$p2)=@_;
196*0Sstevel@tonic-gate	local($l,$ll,$t);
197*0Sstevel@tonic-gate	local(%special)=(	"roll",0xD1C0,"rorl",0xD1C8,
198*0Sstevel@tonic-gate				"rcll",0xD1D0,"rcrl",0xD1D8,
199*0Sstevel@tonic-gate				"shll",0xD1E0,"shrl",0xD1E8,
200*0Sstevel@tonic-gate				"sarl",0xD1F8);
201*0Sstevel@tonic-gate
202*0Sstevel@tonic-gate	if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1))
203*0Sstevel@tonic-gate		{
204*0Sstevel@tonic-gate		$op=$special{$name}|$reg_val{$p1};
205*0Sstevel@tonic-gate		$tmp1=sprintf(".byte %d\n",($op>>8)&0xff);
206*0Sstevel@tonic-gate		$tmp2=sprintf(".byte %d\t",$op     &0xff);
207*0Sstevel@tonic-gate		push(@out,$tmp1);
208*0Sstevel@tonic-gate		push(@out,$tmp2);
209*0Sstevel@tonic-gate
210*0Sstevel@tonic-gate		$p2=&conv($p2);
211*0Sstevel@tonic-gate		$p1=&conv($p1);
212*0Sstevel@tonic-gate		&main'comment("$name $p2 $p1");
213*0Sstevel@tonic-gate		return;
214*0Sstevel@tonic-gate		}
215*0Sstevel@tonic-gate
216*0Sstevel@tonic-gate	push(@out,"\t$name\t");
217*0Sstevel@tonic-gate	$t=&conv($p2).",";
218*0Sstevel@tonic-gate	$l=length($t);
219*0Sstevel@tonic-gate	push(@out,$t);
220*0Sstevel@tonic-gate	$ll=4-($l+9)/8;
221*0Sstevel@tonic-gate	$tmp1=sprintf("\t" x $ll);
222*0Sstevel@tonic-gate	push(@out,$tmp1);
223*0Sstevel@tonic-gate	push(@out,&conv($p1)."\n");
224*0Sstevel@tonic-gate	}
225*0Sstevel@tonic-gate
226*0Sstevel@tonic-gatesub out1
227*0Sstevel@tonic-gate	{
228*0Sstevel@tonic-gate	local($name,$p1)=@_;
229*0Sstevel@tonic-gate	local($l,$t);
230*0Sstevel@tonic-gate	local(%special)=("bswapl",0x0FC8);
231*0Sstevel@tonic-gate
232*0Sstevel@tonic-gate	if ((defined($special{$name})) && defined($regs{$p1}))
233*0Sstevel@tonic-gate		{
234*0Sstevel@tonic-gate		$op=$special{$name}|$reg_val{$p1};
235*0Sstevel@tonic-gate		$tmp1=sprintf(".byte %d\n",($op>>8)&0xff);
236*0Sstevel@tonic-gate		$tmp2=sprintf(".byte %d\t",$op     &0xff);
237*0Sstevel@tonic-gate		push(@out,$tmp1);
238*0Sstevel@tonic-gate		push(@out,$tmp2);
239*0Sstevel@tonic-gate
240*0Sstevel@tonic-gate		$p2=&conv($p2);
241*0Sstevel@tonic-gate		$p1=&conv($p1);
242*0Sstevel@tonic-gate		&main'comment("$name $p2 $p1");
243*0Sstevel@tonic-gate		return;
244*0Sstevel@tonic-gate		}
245*0Sstevel@tonic-gate
246*0Sstevel@tonic-gate	push(@out,"\t$name\t".&conv($p1)."\n");
247*0Sstevel@tonic-gate	}
248*0Sstevel@tonic-gate
249*0Sstevel@tonic-gatesub out1p
250*0Sstevel@tonic-gate	{
251*0Sstevel@tonic-gate	local($name,$p1)=@_;
252*0Sstevel@tonic-gate	local($l,$t);
253*0Sstevel@tonic-gate
254*0Sstevel@tonic-gate	push(@out,"\t$name\t*".&conv($p1)."\n");
255*0Sstevel@tonic-gate	}
256*0Sstevel@tonic-gate
257*0Sstevel@tonic-gatesub out0
258*0Sstevel@tonic-gate	{
259*0Sstevel@tonic-gate	push(@out,"\t$_[0]\n");
260*0Sstevel@tonic-gate	}
261*0Sstevel@tonic-gate
262*0Sstevel@tonic-gatesub conv
263*0Sstevel@tonic-gate	{
264*0Sstevel@tonic-gate	local($p)=@_;
265*0Sstevel@tonic-gate
266*0Sstevel@tonic-gate#	$p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
267*0Sstevel@tonic-gate
268*0Sstevel@tonic-gate	$p=$regs{$p} if (defined($regs{$p}));
269*0Sstevel@tonic-gate
270*0Sstevel@tonic-gate	$p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/;
271*0Sstevel@tonic-gate	$p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/;
272*0Sstevel@tonic-gate	return $p;
273*0Sstevel@tonic-gate	}
274*0Sstevel@tonic-gate
275*0Sstevel@tonic-gatesub main'file
276*0Sstevel@tonic-gate	{
277*0Sstevel@tonic-gate	local($file)=@_;
278*0Sstevel@tonic-gate
279*0Sstevel@tonic-gate	local($tmp)=<<"EOF";
280*0Sstevel@tonic-gate	.file	"$file.s"
281*0Sstevel@tonic-gate	.version	"01.01"
282*0Sstevel@tonic-gategcc2_compiled.:
283*0Sstevel@tonic-gateEOF
284*0Sstevel@tonic-gate	push(@out,$tmp);
285*0Sstevel@tonic-gate	}
286*0Sstevel@tonic-gate
287*0Sstevel@tonic-gatesub main'function_begin
288*0Sstevel@tonic-gate	{
289*0Sstevel@tonic-gate	local($func)=@_;
290*0Sstevel@tonic-gate
291*0Sstevel@tonic-gate	&main'external_label($func);
292*0Sstevel@tonic-gate	$func=$under.$func;
293*0Sstevel@tonic-gate
294*0Sstevel@tonic-gate	local($tmp)=<<"EOF";
295*0Sstevel@tonic-gate.text
296*0Sstevel@tonic-gate	.align $align
297*0Sstevel@tonic-gate.globl $func
298*0Sstevel@tonic-gateEOF
299*0Sstevel@tonic-gate	push(@out,$tmp);
300*0Sstevel@tonic-gate	if ($main'cpp)
301*0Sstevel@tonic-gate		{ $tmp=push(@out,"\tTYPE($func,\@function)\n"); }
302*0Sstevel@tonic-gate	elsif ($main'gaswin)
303*0Sstevel@tonic-gate		{ $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
304*0Sstevel@tonic-gate	else	{ $tmp=push(@out,"\t.type\t$func,\@function\n"); }
305*0Sstevel@tonic-gate	push(@out,"$func:\n");
306*0Sstevel@tonic-gate	$tmp=<<"EOF";
307*0Sstevel@tonic-gate	pushl	%ebp
308*0Sstevel@tonic-gate	pushl	%ebx
309*0Sstevel@tonic-gate	pushl	%esi
310*0Sstevel@tonic-gate	pushl	%edi
311*0Sstevel@tonic-gate
312*0Sstevel@tonic-gateEOF
313*0Sstevel@tonic-gate	push(@out,$tmp);
314*0Sstevel@tonic-gate	$stack=20;
315*0Sstevel@tonic-gate	}
316*0Sstevel@tonic-gate
317*0Sstevel@tonic-gatesub main'function_begin_B
318*0Sstevel@tonic-gate	{
319*0Sstevel@tonic-gate	local($func,$extra)=@_;
320*0Sstevel@tonic-gate
321*0Sstevel@tonic-gate	&main'external_label($func);
322*0Sstevel@tonic-gate	$func=$under.$func;
323*0Sstevel@tonic-gate
324*0Sstevel@tonic-gate	local($tmp)=<<"EOF";
325*0Sstevel@tonic-gate.text
326*0Sstevel@tonic-gate	.align $align
327*0Sstevel@tonic-gate.globl $func
328*0Sstevel@tonic-gateEOF
329*0Sstevel@tonic-gate	push(@out,$tmp);
330*0Sstevel@tonic-gate	if ($main'cpp)
331*0Sstevel@tonic-gate		{ push(@out,"\tTYPE($func,\@function)\n"); }
332*0Sstevel@tonic-gate	elsif ($main'gaswin)
333*0Sstevel@tonic-gate		{ $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
334*0Sstevel@tonic-gate	else	{ push(@out,"\t.type	$func,\@function\n"); }
335*0Sstevel@tonic-gate	push(@out,"$func:\n");
336*0Sstevel@tonic-gate	$stack=4;
337*0Sstevel@tonic-gate	}
338*0Sstevel@tonic-gate
339*0Sstevel@tonic-gatesub main'function_end
340*0Sstevel@tonic-gate	{
341*0Sstevel@tonic-gate	local($func)=@_;
342*0Sstevel@tonic-gate
343*0Sstevel@tonic-gate	$func=$under.$func;
344*0Sstevel@tonic-gate
345*0Sstevel@tonic-gate	local($tmp)=<<"EOF";
346*0Sstevel@tonic-gate	popl	%edi
347*0Sstevel@tonic-gate	popl	%esi
348*0Sstevel@tonic-gate	popl	%ebx
349*0Sstevel@tonic-gate	popl	%ebp
350*0Sstevel@tonic-gate	ret
351*0Sstevel@tonic-gate.L_${func}_end:
352*0Sstevel@tonic-gateEOF
353*0Sstevel@tonic-gate	push(@out,$tmp);
354*0Sstevel@tonic-gate
355*0Sstevel@tonic-gate	if ($main'cpp)
356*0Sstevel@tonic-gate		{ push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); }
357*0Sstevel@tonic-gate	elsif ($main'gaswin)
358*0Sstevel@tonic-gate                { $tmp=push(@out,"\t.align 4\n"); }
359*0Sstevel@tonic-gate	else	{ push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); }
360*0Sstevel@tonic-gate	push(@out,".ident	\"$func\"\n");
361*0Sstevel@tonic-gate	$stack=0;
362*0Sstevel@tonic-gate	%label=();
363*0Sstevel@tonic-gate	}
364*0Sstevel@tonic-gate
365*0Sstevel@tonic-gatesub main'function_end_A
366*0Sstevel@tonic-gate	{
367*0Sstevel@tonic-gate	local($func)=@_;
368*0Sstevel@tonic-gate
369*0Sstevel@tonic-gate	local($tmp)=<<"EOF";
370*0Sstevel@tonic-gate	popl	%edi
371*0Sstevel@tonic-gate	popl	%esi
372*0Sstevel@tonic-gate	popl	%ebx
373*0Sstevel@tonic-gate	popl	%ebp
374*0Sstevel@tonic-gate	ret
375*0Sstevel@tonic-gateEOF
376*0Sstevel@tonic-gate	push(@out,$tmp);
377*0Sstevel@tonic-gate	}
378*0Sstevel@tonic-gate
379*0Sstevel@tonic-gatesub main'function_end_B
380*0Sstevel@tonic-gate	{
381*0Sstevel@tonic-gate	local($func)=@_;
382*0Sstevel@tonic-gate
383*0Sstevel@tonic-gate	$func=$under.$func;
384*0Sstevel@tonic-gate
385*0Sstevel@tonic-gate	push(@out,".L_${func}_end:\n");
386*0Sstevel@tonic-gate	if ($main'cpp)
387*0Sstevel@tonic-gate		{ push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); }
388*0Sstevel@tonic-gate        elsif ($main'gaswin)
389*0Sstevel@tonic-gate                { push(@out,"\t.align 4\n"); }
390*0Sstevel@tonic-gate	else	{ push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); }
391*0Sstevel@tonic-gate	push(@out,".ident	\"desasm.pl\"\n");
392*0Sstevel@tonic-gate	$stack=0;
393*0Sstevel@tonic-gate	%label=();
394*0Sstevel@tonic-gate	}
395*0Sstevel@tonic-gate
396*0Sstevel@tonic-gatesub main'wparam
397*0Sstevel@tonic-gate	{
398*0Sstevel@tonic-gate	local($num)=@_;
399*0Sstevel@tonic-gate
400*0Sstevel@tonic-gate	return(&main'DWP($stack+$num*4,"esp","",0));
401*0Sstevel@tonic-gate	}
402*0Sstevel@tonic-gate
403*0Sstevel@tonic-gatesub main'stack_push
404*0Sstevel@tonic-gate	{
405*0Sstevel@tonic-gate	local($num)=@_;
406*0Sstevel@tonic-gate	$stack+=$num*4;
407*0Sstevel@tonic-gate	&main'sub("esp",$num*4);
408*0Sstevel@tonic-gate	}
409*0Sstevel@tonic-gate
410*0Sstevel@tonic-gatesub main'stack_pop
411*0Sstevel@tonic-gate	{
412*0Sstevel@tonic-gate	local($num)=@_;
413*0Sstevel@tonic-gate	$stack-=$num*4;
414*0Sstevel@tonic-gate	&main'add("esp",$num*4);
415*0Sstevel@tonic-gate	}
416*0Sstevel@tonic-gate
417*0Sstevel@tonic-gatesub main'swtmp
418*0Sstevel@tonic-gate	{
419*0Sstevel@tonic-gate	return(&main'DWP($_[0]*4,"esp","",0));
420*0Sstevel@tonic-gate	}
421*0Sstevel@tonic-gate
422*0Sstevel@tonic-gate# Should use swtmp, which is above esp.  Linix can trash the stack above esp
423*0Sstevel@tonic-gate#sub main'wtmp
424*0Sstevel@tonic-gate#	{
425*0Sstevel@tonic-gate#	local($num)=@_;
426*0Sstevel@tonic-gate#
427*0Sstevel@tonic-gate#	return(&main'DWP(-($num+1)*4,"esp","",0));
428*0Sstevel@tonic-gate#	}
429*0Sstevel@tonic-gate
430*0Sstevel@tonic-gatesub main'comment
431*0Sstevel@tonic-gate	{
432*0Sstevel@tonic-gate	if ($main'elf)	# GNU and SVR4 as'es use different comment delimiters,
433*0Sstevel@tonic-gate		{	# so we just skip comments...
434*0Sstevel@tonic-gate		push(@out,"\n");
435*0Sstevel@tonic-gate		return;
436*0Sstevel@tonic-gate		}
437*0Sstevel@tonic-gate	foreach (@_)
438*0Sstevel@tonic-gate		{
439*0Sstevel@tonic-gate		if (/^\s*$/)
440*0Sstevel@tonic-gate			{ push(@out,"\n"); }
441*0Sstevel@tonic-gate		else
442*0Sstevel@tonic-gate			{ push(@out,"\t$com_start $_ $com_end\n"); }
443*0Sstevel@tonic-gate		}
444*0Sstevel@tonic-gate	}
445*0Sstevel@tonic-gate
446*0Sstevel@tonic-gatesub main'label
447*0Sstevel@tonic-gate	{
448*0Sstevel@tonic-gate	if (!defined($label{$_[0]}))
449*0Sstevel@tonic-gate		{
450*0Sstevel@tonic-gate		$label{$_[0]}=".${label}${_[0]}";
451*0Sstevel@tonic-gate		$label++;
452*0Sstevel@tonic-gate		}
453*0Sstevel@tonic-gate	return($label{$_[0]});
454*0Sstevel@tonic-gate	}
455*0Sstevel@tonic-gate
456*0Sstevel@tonic-gatesub main'set_label
457*0Sstevel@tonic-gate	{
458*0Sstevel@tonic-gate	if (!defined($label{$_[0]}))
459*0Sstevel@tonic-gate		{
460*0Sstevel@tonic-gate		$label{$_[0]}=".${label}${_[0]}";
461*0Sstevel@tonic-gate		$label++;
462*0Sstevel@tonic-gate		}
463*0Sstevel@tonic-gate	push(@out,".align $align\n") if ($_[1] != 0);
464*0Sstevel@tonic-gate	push(@out,"$label{$_[0]}:\n");
465*0Sstevel@tonic-gate	}
466*0Sstevel@tonic-gate
467*0Sstevel@tonic-gatesub main'file_end
468*0Sstevel@tonic-gate	{
469*0Sstevel@tonic-gate	if ($const ne "")
470*0Sstevel@tonic-gate		{
471*0Sstevel@tonic-gate		push(@out,".section .rodata\n");
472*0Sstevel@tonic-gate		push(@out,$const);
473*0Sstevel@tonic-gate		$const="";
474*0Sstevel@tonic-gate		}
475*0Sstevel@tonic-gate	}
476*0Sstevel@tonic-gate
477*0Sstevel@tonic-gatesub main'data_word
478*0Sstevel@tonic-gate	{
479*0Sstevel@tonic-gate	push(@out,"\t.long $_[0]\n");
480*0Sstevel@tonic-gate	}
481*0Sstevel@tonic-gate
482*0Sstevel@tonic-gate# debug output functions: puts, putx, printf
483*0Sstevel@tonic-gate
484*0Sstevel@tonic-gatesub main'puts
485*0Sstevel@tonic-gate	{
486*0Sstevel@tonic-gate	&pushvars();
487*0Sstevel@tonic-gate	&main'push('$Lstring' . ++$constl);
488*0Sstevel@tonic-gate	&main'call('puts');
489*0Sstevel@tonic-gate	$stack-=4;
490*0Sstevel@tonic-gate	&main'add("esp",4);
491*0Sstevel@tonic-gate	&popvars();
492*0Sstevel@tonic-gate
493*0Sstevel@tonic-gate	$const .= "Lstring$constl:\n\t.string \"@_[0]\"\n";
494*0Sstevel@tonic-gate	}
495*0Sstevel@tonic-gate
496*0Sstevel@tonic-gatesub main'putx
497*0Sstevel@tonic-gate	{
498*0Sstevel@tonic-gate	&pushvars();
499*0Sstevel@tonic-gate	&main'push($_[0]);
500*0Sstevel@tonic-gate	&main'push('$Lstring' . ++$constl);
501*0Sstevel@tonic-gate	&main'call('printf');
502*0Sstevel@tonic-gate	&main'add("esp",8);
503*0Sstevel@tonic-gate	$stack-=8;
504*0Sstevel@tonic-gate	&popvars();
505*0Sstevel@tonic-gate
506*0Sstevel@tonic-gate	$const .= "Lstring$constl:\n\t.string \"\%X\"\n";
507*0Sstevel@tonic-gate	}
508*0Sstevel@tonic-gate
509*0Sstevel@tonic-gatesub main'printf
510*0Sstevel@tonic-gate	{
511*0Sstevel@tonic-gate	$ostack = $stack;
512*0Sstevel@tonic-gate	&pushvars();
513*0Sstevel@tonic-gate	for ($i = @_ - 1; $i >= 0; $i--)
514*0Sstevel@tonic-gate		{
515*0Sstevel@tonic-gate		if ($i == 0) # change this to support %s format strings
516*0Sstevel@tonic-gate			{
517*0Sstevel@tonic-gate			&main'push('$Lstring' . ++$constl);
518*0Sstevel@tonic-gate			$const .= "Lstring$constl:\n\t.string \"@_[$i]\"\n";
519*0Sstevel@tonic-gate			}
520*0Sstevel@tonic-gate		else
521*0Sstevel@tonic-gate			{
522*0Sstevel@tonic-gate			if ($_[$i] =~ /([0-9]*)\(%esp\)/)
523*0Sstevel@tonic-gate				{
524*0Sstevel@tonic-gate				&main'push(($1 + $stack - $ostack) . '(%esp)');
525*0Sstevel@tonic-gate				}
526*0Sstevel@tonic-gate			else
527*0Sstevel@tonic-gate				{
528*0Sstevel@tonic-gate				&main'push($_[$i]);
529*0Sstevel@tonic-gate				}
530*0Sstevel@tonic-gate			}
531*0Sstevel@tonic-gate		}
532*0Sstevel@tonic-gate	&main'call('printf');
533*0Sstevel@tonic-gate	$stack-=4*@_;
534*0Sstevel@tonic-gate	&main'add("esp",4*@_);
535*0Sstevel@tonic-gate	&popvars();
536*0Sstevel@tonic-gate	}
537*0Sstevel@tonic-gate
538*0Sstevel@tonic-gatesub pushvars
539*0Sstevel@tonic-gate	{
540*0Sstevel@tonic-gate	&main'pushf();
541*0Sstevel@tonic-gate	&main'push("edx");
542*0Sstevel@tonic-gate	&main'push("ecx");
543*0Sstevel@tonic-gate	&main'push("eax");
544*0Sstevel@tonic-gate	}
545*0Sstevel@tonic-gate
546*0Sstevel@tonic-gatesub popvars
547*0Sstevel@tonic-gate	{
548*0Sstevel@tonic-gate	&main'pop("eax");
549*0Sstevel@tonic-gate	&main'pop("ecx");
550*0Sstevel@tonic-gate	&main'pop("edx");
551*0Sstevel@tonic-gate	&main'popf();
552*0Sstevel@tonic-gate	}
553*0Sstevel@tonic-gate
554*0Sstevel@tonic-gatesub main'picmeup
555*0Sstevel@tonic-gate	{
556*0Sstevel@tonic-gate	local($dst,$sym)=@_;
557*0Sstevel@tonic-gate	if ($main'cpp)
558*0Sstevel@tonic-gate		{
559*0Sstevel@tonic-gate		local($tmp)=<<___;
560*0Sstevel@tonic-gate#if (defined(ELF) || defined(SOL)) && defined(PIC)
561*0Sstevel@tonic-gate	.align	8
562*0Sstevel@tonic-gate	call	1f
563*0Sstevel@tonic-gate1:	popl	$regs{$dst}
564*0Sstevel@tonic-gate	addl	\$_GLOBAL_OFFSET_TABLE_+[.-1b],$regs{$dst}
565*0Sstevel@tonic-gate	movl	$sym\@GOT($regs{$dst}),$regs{$dst}
566*0Sstevel@tonic-gate#else
567*0Sstevel@tonic-gate	leal	$sym,$regs{$dst}
568*0Sstevel@tonic-gate#endif
569*0Sstevel@tonic-gate___
570*0Sstevel@tonic-gate		push(@out,$tmp);
571*0Sstevel@tonic-gate		}
572*0Sstevel@tonic-gate	elsif ($main'pic && ($main'elf || $main'aout))
573*0Sstevel@tonic-gate		{
574*0Sstevel@tonic-gate		push(@out,"\t.align\t8\n");
575*0Sstevel@tonic-gate		&main'call(&main'label("PIC_me_up"));
576*0Sstevel@tonic-gate		&main'set_label("PIC_me_up");
577*0Sstevel@tonic-gate		&main'blindpop($dst);
578*0Sstevel@tonic-gate		&main'add($dst,"\$$under"."_GLOBAL_OFFSET_TABLE_+[.-".
579*0Sstevel@tonic-gate				&main'label("PIC_me_up") . "]");
580*0Sstevel@tonic-gate		&main'mov($dst,&main'DWP($sym."\@GOT",$dst));
581*0Sstevel@tonic-gate		}
582*0Sstevel@tonic-gate	else
583*0Sstevel@tonic-gate		{
584*0Sstevel@tonic-gate		&main'lea($dst,&main'DWP($sym));
585*0Sstevel@tonic-gate		}
586*0Sstevel@tonic-gate	}
587*0Sstevel@tonic-gate
588*0Sstevel@tonic-gatesub main'blindpop { &out1("popl",@_); }
589