1221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#!/usr/bin/env perl
2221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
3221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrompackage x86gas;
4221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
5221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom*out=\@::out;
6221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
7221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$::lbdecor=$::aout?"L":".L";		# local label decoration
8221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$nmdecor=($::aout or $::coff)?"_":"";	# external name decoration
9221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
10221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$initseg="";
11221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
12221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$align=16;
13221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$align=log($align)/log(2) if ($::aout);
14221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$com_start="#" if ($::aout or $::coff);
15221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
16221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub opsize()
17221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ my $reg=shift;
18221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if    ($reg =~ m/^%e/o)		{ "l"; }
19221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    elsif ($reg =~ m/^%[a-d][hl]$/o)	{ "b"; }
20221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    elsif ($reg =~ m/^%[xm]/o)		{ undef; }
21221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    else				{ "w"; }
22221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
23221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
24221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# swap arguments;
25221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# expand opcode with size suffix;
26221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# prefix numeric constants with $;
27221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::generic
28221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ my($opcode,@arg)=@_;
29221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  my($suffix,$dst,$src);
30221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
31221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    @arg=reverse(@arg);
32221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
33221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    for (@arg)
34221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {	s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o;	# gp registers
35221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	s/^([xy]?mm[0-7])$/%$1/o;		# xmm/mmx registers
36221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	s/^(\-?[0-9]+)$/\$$1/o;			# constants
37221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	s/^(\-?0x[0-9a-f]+)$/\$$1/o;		# constants
38221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
39221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
40221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    $dst = $arg[$#arg]		if ($#arg>=0);
41221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    $src = $arg[$#arg-1]	if ($#arg>=1);
42221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if    ($dst =~ m/^%/o)	{ $suffix=&opsize($dst); }
43221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    elsif ($src =~ m/^%/o)	{ $suffix=&opsize($src); }
44221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    else			{ $suffix="l";           }
45221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    undef $suffix if ($dst =~ m/^%[xm]/o || $src =~ m/^%[xm]/o);
46221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
47221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if ($#_==0)				{ &::emit($opcode);		}
48392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom    elsif ($#_==1 && $opcode =~ m/^(call|clflush|j|loop|set)/o)
49392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					{ &::emit($opcode,@arg);	}
50221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    else				{ &::emit($opcode.$suffix,@arg);}
51221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
52221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  1;
53221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
54221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#
55221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# opcodes not covered by ::generic above, mostly inconsistent namings...
56221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#
57221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::movzx	{ &::movzb(@_);			}
58221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::pushfd	{ &::pushfl;			}
59221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::popfd	{ &::popfl;			}
60221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::cpuid	{ &::emit(".byte\t0x0f,0xa2");	}
61221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::rdtsc	{ &::emit(".byte\t0x0f,0x31");	}
62221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
63221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
64221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::call_ptr	{ &::generic("call","*$_[0]");	}
65221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::jmp_ptr	{ &::generic("jmp","*$_[0]");	}
66221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
67221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom*::bswap = sub	{ &::emit("bswap","%$_[0]");	} if (!$::i386);
68221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
69221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::DWP
70221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ my($addr,$reg1,$reg2,$idx)=@_;
71221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  my $ret="";
72221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
73221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    $addr =~ s/^\s+//;
74221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    # prepend global references with optional underscore
75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige;
76221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
77221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    $reg1 = "%$reg1" if ($reg1);
78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    $reg2 = "%$reg2" if ($reg2);
79221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
80221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    $ret .= $addr if (($addr ne "") && ($addr ne 0));
81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if ($reg2)
83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {	$idx!= 0 or $idx=1;
84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$ret .= "($reg1,$reg2,$idx)";
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    elsif ($reg1)
87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {	$ret .= "($reg1)";	}
88221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
89221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  $ret;
90221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
91221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::QWP	{ &::DWP(@_);	}
92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::BP	{ &::DWP(@_);	}
93392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromsub ::WP	{ &::DWP(@_);	}
94221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::BC	{ @_;		}
95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::DWC	{ @_;		}
96221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
97221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::file
98221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{   push(@out,".file\t\"$_[0].s\"\n.text\n");	}
99221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
100221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::function_begin_B
101221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ my $func=shift;
102221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  my $global=($func !~ /^_/);
103221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  my $begin="${::lbdecor}_${func}_begin";
104221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
105221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    &::LABEL($func,$global?"$begin":"$nmdecor$func");
106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    $func=$nmdecor.$func;
107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    push(@out,".globl\t$func\n")	if ($global);
109221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if ($::coff)
110221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {	push(@out,".def\t$func;\t.scl\t".(3-$global).";\t.type\t32;\t.endef\n"); }
111221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    elsif (($::aout and !$::pic) or $::macosx)
112221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    { }
113221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    else
114221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {	push(@out,".type	$func,\@function\n"); }
115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    push(@out,".align\t$align\n");
116221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    push(@out,"$func:\n");
117221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    push(@out,"$begin:\n")		if ($global);
118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    $::stack=4;
119221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
121221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::function_end_B
122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ my $func=shift;
123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    push(@out,".size\t$nmdecor$func,.-".&::LABEL($func)."\n") if ($::elf);
124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    $::stack=0;
125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    &::wipe_labels();
126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::comment
129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!defined($com_start) or $::elf)
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{	# Regarding $::elf above...
132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			# GNU and SVR4 as'es use different comment delimiters,
133221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		push(@out,"\n");	# so we just skip ELF comments...
134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return;
135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	foreach (@_)
137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (/^\s*$/)
139221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{ push(@out,"\n"); }
140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else
141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{ push(@out,"\t$com_start $_ $com_end\n"); }
142221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
143221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
145221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::external_label
146221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{   foreach(@_) { &::LABEL($_,$nmdecor.$_); }   }
147221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
148221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::public_label
149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{   push(@out,".globl\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");   }
150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::file_end
152392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{   if ($::macosx)
153221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {	if (%non_lazy_ptr)
154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    	{   push(@out,".section __IMPORT,__pointers,non_lazy_symbol_pointers\n");
155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    foreach $i (keys %non_lazy_ptr)
156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    {	push(@out,"$non_lazy_ptr{$i}:\n.indirect_symbol\t$i\n.long\t0\n");   }
157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
159392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom    if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
160392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,8";
161392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if ($::macosx)	{ push (@out,"$tmp,2\n"); }
162392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	elsif ($::elf)	{ push (@out,"$tmp,4\n"); }
163392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else		{ push (@out,"$tmp\n"); }
164392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom    }
165221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    push(@out,$initseg) if ($initseg);
166221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
167221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
168221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::data_byte	{   push(@out,".byte\t".join(',',@_)."\n");   }
169392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromsub ::data_short{   push(@out,".value\t".join(',',@_)."\n");  }
170221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::data_word {   push(@out,".long\t".join(',',@_)."\n");   }
171221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
172221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::align
173221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ my $val=$_[0],$p2,$i;
174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if ($::aout)
175221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {	for ($p2=0;$val!=0;$val>>=1) { $p2++; }
176221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$val=$p2-1;
177221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$val.=",0x90";
178221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
179221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    push(@out,".align\t$val\n");
180221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
181221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
182221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::picmeup
183221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ my($dst,$sym,$base,$reflabel)=@_;
184221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
185392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom    if (($::pic && ($::elf || $::aout)) || $::macosx)
186221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {	if (!defined($base))
187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{   &::call(&::label("PIC_me_up"));
188221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    &::set_label("PIC_me_up");
189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    &::blindpop($dst);
190221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    $base=$dst;
191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    $reflabel=&::label("PIC_me_up");
192221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
193221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if ($::macosx)
194221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{   my $indirect=&::static_label("$nmdecor$sym\$non_lazy_ptr");
195221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    &::mov($dst,&::DWP("$indirect-$reflabel",$base));
196221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    $non_lazy_ptr{"$nmdecor$sym"}=$indirect;
197221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
198221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
199221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{   &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]",
200221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			    $base));
201221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    &::mov($dst,&::DWP("$sym\@GOT",$dst));
202221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
203221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    else
205221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {	&::lea($dst,&::DWP($sym));	}
206221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
207221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
208221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::initseg
209221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ my $f=$nmdecor.shift;
210221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
211392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom    if ($::android)
212392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom    {	$initseg.=<<___;
213392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom.section	.init_array
214392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom.align	4
215392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom.long	$f
216392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom___
217392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom    }
218392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom    elsif ($::elf)
219221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {	$initseg.=<<___;
220221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.section	.init
221221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	call	$f
222221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
223221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
224221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    elsif ($::coff)
225221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {   $initseg.=<<___;	# applies to both Cygwin and Mingw
226221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.section	.ctors
227221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.long	$f
228221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
229221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    elsif ($::macosx)
231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {	$initseg.=<<___;
232221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.mod_init_func
233221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.align 2
234221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.long   $f
235221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
236221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
237221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    elsif ($::aout)
238221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    {	my $ctor="${nmdecor}_GLOBAL_\$I\$$f";
239221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$initseg.=".text\n";
240221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$initseg.=".type	$ctor,\@function\n" if ($::pic);
241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	$initseg.=<<___;	# OpenBSD way...
242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.globl	$ctor
243221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom.align	2
244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom$ctor:
245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	jmp	$f
246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom___
247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromsub ::dataseg
251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{   push(@out,".data\n");   }
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
25379a629e841a8c33b1a5c4e48529905c9812ea307Dmitriy Ivanov*::hidden = sub { push(@out,".hidden\t$nmdecor$_[0]\n"); } if ($::elf);
25479a629e841a8c33b1a5c4e48529905c9812ea307Dmitriy Ivanov
255221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom1;
256