summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/perlasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/perlasm')
-rw-r--r--src/lib/libcrypto/perlasm/cbc.pl4
-rw-r--r--src/lib/libcrypto/perlasm/x86asm.pl27
-rw-r--r--src/lib/libcrypto/perlasm/x86ms.pl122
-rw-r--r--src/lib/libcrypto/perlasm/x86nasm.pl153
-rw-r--r--src/lib/libcrypto/perlasm/x86unix.pl234
5 files changed, 427 insertions, 113 deletions
diff --git a/src/lib/libcrypto/perlasm/cbc.pl b/src/lib/libcrypto/perlasm/cbc.pl
index 22149c680e..e43dc9ae15 100644
--- a/src/lib/libcrypto/perlasm/cbc.pl
+++ b/src/lib/libcrypto/perlasm/cbc.pl
@@ -322,7 +322,8 @@ sub cbc
322 322
323 &function_end_A($name); 323 &function_end_A($name);
324 324
325 &set_label("cbc_enc_jmp_table",1); 325 &align(64);
326 &set_label("cbc_enc_jmp_table");
326 &data_word("0"); 327 &data_word("0");
327 &data_word(&label("ej1")."-".&label("PIC_point")); 328 &data_word(&label("ej1")."-".&label("PIC_point"));
328 &data_word(&label("ej2")."-".&label("PIC_point")); 329 &data_word(&label("ej2")."-".&label("PIC_point"));
@@ -341,6 +342,7 @@ sub cbc
341 #&data_word(&label("dj5")."-".&label("PIC_point")); 342 #&data_word(&label("dj5")."-".&label("PIC_point"));
342 #&data_word(&label("dj6")."-".&label("PIC_point")); 343 #&data_word(&label("dj6")."-".&label("PIC_point"));
343 #&data_word(&label("dj7")."-".&label("PIC_point")); 344 #&data_word(&label("dj7")."-".&label("PIC_point"));
345 &align(64);
344 346
345 &function_end_B($name); 347 &function_end_B($name);
346 348
diff --git a/src/lib/libcrypto/perlasm/x86asm.pl b/src/lib/libcrypto/perlasm/x86asm.pl
index c3de90c65d..f535c9c7fa 100644
--- a/src/lib/libcrypto/perlasm/x86asm.pl
+++ b/src/lib/libcrypto/perlasm/x86asm.pl
@@ -18,7 +18,7 @@ sub main'asm_init
18 ($type,$fn,$i386)=@_; 18 ($type,$fn,$i386)=@_;
19 $filename=$fn; 19 $filename=$fn;
20 20
21 $elf=$cpp=$sol=$aout=$win32=$gaswin=$openbsd=0; 21 $elf=$cpp=$coff=$aout=$win32=$netware=$mwerks=$openbsd=0;
22 if ( ($type eq "elf")) 22 if ( ($type eq "elf"))
23 { $elf=1; require "x86unix.pl"; } 23 { $elf=1; require "x86unix.pl"; }
24 elsif ( ($type eq "openbsd-elf")) 24 elsif ( ($type eq "openbsd-elf"))
@@ -27,28 +27,31 @@ sub main'asm_init
27 { $openbsd=1; require "x86unix.pl"; } 27 { $openbsd=1; require "x86unix.pl"; }
28 elsif ( ($type eq "a.out")) 28 elsif ( ($type eq "a.out"))
29 { $aout=1; require "x86unix.pl"; } 29 { $aout=1; require "x86unix.pl"; }
30 elsif ( ($type eq "gaswin")) 30 elsif ( ($type eq "coff" or $type eq "gaswin"))
31 { $gaswin=1; $aout=1; require "x86unix.pl"; } 31 { $coff=1; require "x86unix.pl"; }
32 elsif ( ($type eq "sol"))
33 { $sol=1; require "x86unix.pl"; }
34 elsif ( ($type eq "cpp")) 32 elsif ( ($type eq "cpp"))
35 { $cpp=1; require "x86unix.pl"; } 33 { $cpp=1; require "x86unix.pl"; }
36 elsif ( ($type eq "win32")) 34 elsif ( ($type eq "win32"))
37 { $win32=1; require "x86ms.pl"; } 35 { $win32=1; require "x86ms.pl"; }
38 elsif ( ($type eq "win32n")) 36 elsif ( ($type eq "win32n"))
39 { $win32=1; require "x86nasm.pl"; } 37 { $win32=1; require "x86nasm.pl"; }
38 elsif ( ($type eq "nw-nasm"))
39 { $netware=1; require "x86nasm.pl"; }
40 elsif ( ($type eq "nw-mwasm"))
41 { $netware=1; $mwerks=1; require "x86nasm.pl"; }
40 else 42 else
41 { 43 {
42 print STDERR <<"EOF"; 44 print STDERR <<"EOF";
43Pick one target type from 45Pick one target type from
44 elf - linux, FreeBSD etc 46 elf - Linux, FreeBSD, Solaris x86, etc.
45 a.out - old linux 47 a.out - OpenBSD, DJGPP, etc.
46 sol - x86 solaris 48 coff - GAS/COFF such as Win32 targets
47 cpp - format so x86unix.cpp can be used
48 win32 - Windows 95/Windows NT 49 win32 - Windows 95/Windows NT
49 win32n - Windows 95/Windows NT NASM format 50 win32n - Windows 95/Windows NT NASM format
50 openbsd-elf - OpenBSD elf 51 openbsd-elf - OpenBSD elf
51 openbsd-a.out - OpenBSD a.out 52 openbsd-a.out - OpenBSD a.out
53 nw-nasm - NetWare NASM format
54 nw-mwasm- NetWare Metrowerks Assembler
52EOF 55EOF
53 exit(1); 56 exit(1);
54 } 57 }
@@ -61,7 +64,7 @@ EOF
61&comment("Don't even think of reading this code"); 64&comment("Don't even think of reading this code");
62&comment("It was automatically generated by $filename"); 65&comment("It was automatically generated by $filename");
63&comment("Which is a perl program used to generate the x86 assember for"); 66&comment("Which is a perl program used to generate the x86 assember for");
64&comment("any of elf, a.out, BSDI, Win32, gaswin (for GNU as on Win32) or Solaris"); 67&comment("any of ELF, a.out, COFF, Win32, ...");
65&comment("eric <eay\@cryptsoft.com>"); 68&comment("eric <eay\@cryptsoft.com>");
66&comment(""); 69&comment("");
67 70
@@ -96,7 +99,7 @@ $tmp
96#ifdef OUT 99#ifdef OUT
97#define OK 1 100#define OK 1
98#define ALIGN 4 101#define ALIGN 4
99#if defined(__CYGWIN__) || defined(__DJGPP__) || defined(__MINGW32__) 102#if defined(__CYGWIN__) || defined(__DJGPP__) || (__MINGW32__)
100#undef SIZE 103#undef SIZE
101#undef TYPE 104#undef TYPE
102#define SIZE(a,b) 105#define SIZE(a,b)
@@ -130,6 +133,4 @@ BSDI - a.out with a very primative version of as.
130EOF 133EOF
131 } 134 }
132 135
133sub main'align() {} # swallow align statements in 0.9.7 context
134
1351; 1361;
diff --git a/src/lib/libcrypto/perlasm/x86ms.pl b/src/lib/libcrypto/perlasm/x86ms.pl
index b6bd744057..a0be2934c2 100644
--- a/src/lib/libcrypto/perlasm/x86ms.pl
+++ b/src/lib/libcrypto/perlasm/x86ms.pl
@@ -27,7 +27,13 @@ $label="L000";
27sub main'asm_init_output { @out=(); } 27sub main'asm_init_output { @out=(); }
28sub main'asm_get_output { return(@out); } 28sub main'asm_get_output { return(@out); }
29sub main'get_labels { return(@labels); } 29sub main'get_labels { return(@labels); }
30sub main'external_label { push(@labels,@_); } 30sub main'external_label
31{
32 push(@labels,@_);
33 foreach (@_) {
34 push(@out, "EXTRN\t_$_:DWORD\n");
35 }
36}
31 37
32sub main'LB 38sub main'LB
33 { 39 {
@@ -51,6 +57,11 @@ sub main'DWP
51 &get_mem("DWORD",@_); 57 &get_mem("DWORD",@_);
52 } 58 }
53 59
60sub main'QWP
61 {
62 &get_mem("QWORD",@_);
63 }
64
54sub main'BC 65sub main'BC
55 { 66 {
56 return @_; 67 return @_;
@@ -87,7 +98,7 @@ sub get_mem
87 $reg2=&conv($1); 98 $reg2=&conv($1);
88 $addr="_$2"; 99 $addr="_$2";
89 } 100 }
90 elsif ($addr =~ /^[_a-zA-Z]/) 101 elsif ($addr =~ /^[_a-z][_a-z0-9]*$/i)
91 { 102 {
92 $addr="_$addr"; 103 $addr="_$addr";
93 } 104 }
@@ -128,12 +139,14 @@ sub main'xorb { &out2("xor",@_); }
128sub main'add { &out2("add",@_); } 139sub main'add { &out2("add",@_); }
129sub main'adc { &out2("adc",@_); } 140sub main'adc { &out2("adc",@_); }
130sub main'sub { &out2("sub",@_); } 141sub main'sub { &out2("sub",@_); }
142sub main'sbb { &out2("sbb",@_); }
131sub main'rotl { &out2("rol",@_); } 143sub main'rotl { &out2("rol",@_); }
132sub main'rotr { &out2("ror",@_); } 144sub main'rotr { &out2("ror",@_); }
133sub main'exch { &out2("xchg",@_); } 145sub main'exch { &out2("xchg",@_); }
134sub main'cmp { &out2("cmp",@_); } 146sub main'cmp { &out2("cmp",@_); }
135sub main'lea { &out2("lea",@_); } 147sub main'lea { &out2("lea",@_); }
136sub main'mul { &out1("mul",@_); } 148sub main'mul { &out1("mul",@_); }
149sub main'imul { &out2("imul",@_); }
137sub main'div { &out1("div",@_); } 150sub main'div { &out1("div",@_); }
138sub main'dec { &out1("dec",@_); } 151sub main'dec { &out1("dec",@_); }
139sub main'inc { &out1("inc",@_); } 152sub main'inc { &out1("inc",@_); }
@@ -155,26 +168,54 @@ sub main'jne { &out1("jne",@_); }
155sub main'jno { &out1("jno",@_); } 168sub main'jno { &out1("jno",@_); }
156sub main'push { &out1("push",@_); $stack+=4; } 169sub main'push { &out1("push",@_); $stack+=4; }
157sub main'pop { &out1("pop",@_); $stack-=4; } 170sub main'pop { &out1("pop",@_); $stack-=4; }
171sub main'pushf { &out0("pushfd"); $stack+=4; }
172sub main'popf { &out0("popfd"); $stack-=4; }
158sub main'bswap { &out1("bswap",@_); &using486(); } 173sub main'bswap { &out1("bswap",@_); &using486(); }
159sub main'not { &out1("not",@_); } 174sub main'not { &out1("not",@_); }
160sub main'call { &out1("call",($_[0]=~/^\$L/?'':'_').$_[0]); } 175sub main'call { &out1("call",($_[0]=~/^\$L/?'':'_').$_[0]); }
176sub main'call_ptr { &out1p("call",@_); }
161sub main'ret { &out0("ret"); } 177sub main'ret { &out0("ret"); }
162sub main'nop { &out0("nop"); } 178sub main'nop { &out0("nop"); }
179sub main'test { &out2("test",@_); }
180sub main'bt { &out2("bt",@_); }
181sub main'leave { &out0("leave"); }
182sub main'cpuid { &out0("DW\t0A20Fh"); }
183sub main'rdtsc { &out0("DW\t0310Fh"); }
184sub main'halt { &out0("hlt"); }
163sub main'movz { &out2("movzx",@_); } 185sub main'movz { &out2("movzx",@_); }
186sub main'neg { &out1("neg",@_); }
187sub main'cld { &out0("cld"); }
188
189# SSE2
190sub main'emms { &out0("emms"); }
191sub main'movd { &out2("movd",@_); }
192sub main'movq { &out2("movq",@_); }
193sub main'movdqu { &out2("movdqu",@_); }
194sub main'movdqa { &out2("movdqa",@_); }
195sub main'movdq2q{ &out2("movdq2q",@_); }
196sub main'movq2dq{ &out2("movq2dq",@_); }
197sub main'paddq { &out2("paddq",@_); }
198sub main'pmuludq{ &out2("pmuludq",@_); }
199sub main'psrlq { &out2("psrlq",@_); }
200sub main'psllq { &out2("psllq",@_); }
201sub main'pxor { &out2("pxor",@_); }
202sub main'por { &out2("por",@_); }
203sub main'pand { &out2("pand",@_); }
164 204
165sub out2 205sub out2
166 { 206 {
167 local($name,$p1,$p2)=@_; 207 local($name,$p1,$p2)=@_;
168 local($l,$t); 208 local($l,$t,$line);
169 209
170 push(@out,"\t$name\t"); 210 $line="\t$name\t";
171 $t=&conv($p1).","; 211 $t=&conv($p1).",";
172 $l=length($t); 212 $l=length($t);
173 push(@out,$t); 213 $line.="$t";
174 $l=4-($l+9)/8; 214 $l=4-($l+9)/8;
175 push(@out,"\t" x $l); 215 $line.="\t" x $l;
176 push(@out,&conv($p2)); 216 $line.=&conv($p2);
177 push(@out,"\n"); 217 if ($line=~/\bxmm[0-7]\b/i) { $line=~s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i; }
218 push(@out,$line."\n");
178 } 219 }
179 220
180sub out0 221sub out0
@@ -214,7 +255,9 @@ sub main'file
214 local($tmp)=<<"EOF"; 255 local($tmp)=<<"EOF";
215 TITLE $file.asm 256 TITLE $file.asm
216 .386 257 .386
217.model FLAT 258.model FLAT
259_TEXT\$ SEGMENT PAGE 'CODE'
260
218EOF 261EOF
219 push(@out,$tmp); 262 push(@out,$tmp);
220 } 263 }
@@ -226,7 +269,6 @@ sub main'function_begin
226 push(@labels,$func); 269 push(@labels,$func);
227 270
228 local($tmp)=<<"EOF"; 271 local($tmp)=<<"EOF";
229_TEXT SEGMENT
230PUBLIC _$func 272PUBLIC _$func
231$extra 273$extra
232_$func PROC NEAR 274_$func PROC NEAR
@@ -244,7 +286,6 @@ sub main'function_begin_B
244 local($func,$extra)=@_; 286 local($func,$extra)=@_;
245 287
246 local($tmp)=<<"EOF"; 288 local($tmp)=<<"EOF";
247_TEXT SEGMENT
248PUBLIC _$func 289PUBLIC _$func
249$extra 290$extra
250_$func PROC NEAR 291_$func PROC NEAR
@@ -264,7 +305,6 @@ sub main'function_end
264 pop ebp 305 pop ebp
265 ret 306 ret
266_$func ENDP 307_$func ENDP
267_TEXT ENDS
268EOF 308EOF
269 push(@out,$tmp); 309 push(@out,$tmp);
270 $stack=0; 310 $stack=0;
@@ -277,7 +317,6 @@ sub main'function_end_B
277 317
278 local($tmp)=<<"EOF"; 318 local($tmp)=<<"EOF";
279_$func ENDP 319_$func ENDP
280_TEXT ENDS
281EOF 320EOF
282 push(@out,$tmp); 321 push(@out,$tmp);
283 $stack=0; 322 $stack=0;
@@ -300,6 +339,20 @@ EOF
300 339
301sub main'file_end 340sub main'file_end
302 { 341 {
342 # try to detect if SSE2 or MMX extensions were used...
343 my $xmmheader=<<___;
344.686
345.XMM
346IF \@Version LT 800
347XMMWORD STRUCT 16
348 DQ 2 dup (?)
349XMMWORD ENDS
350ENDIF
351___
352 if (grep {/\b[x]?mm[0-7]\b/i} @out) {
353 grep {s/\.[3-7]86/$xmmheader/} @out;
354 }
355 push(@out,"_TEXT\$ ENDS\n");
303 push(@out,"END\n"); 356 push(@out,"END\n");
304 } 357 }
305 358
@@ -331,6 +384,12 @@ sub main'comment
331 } 384 }
332 } 385 }
333 386
387sub main'public_label
388 {
389 $label{$_[0]}="_$_[0]" if (!defined($label{$_[0]}));
390 push(@out,"PUBLIC\t$label{$_[0]}\n");
391 }
392
334sub main'label 393sub main'label
335 { 394 {
336 if (!defined($label{$_[0]})) 395 if (!defined($label{$_[0]}))
@@ -348,19 +407,37 @@ sub main'set_label
348 $label{$_[0]}="\$${label}${_[0]}"; 407 $label{$_[0]}="\$${label}${_[0]}";
349 $label++; 408 $label++;
350 } 409 }
410 if ($_[1]!=0 && $_[1]>1)
411 {
412 main'align($_[1]);
413 }
351 if((defined $_[2]) && ($_[2] == 1)) 414 if((defined $_[2]) && ($_[2] == 1))
352 { 415 {
353 push(@out,"$label{$_[0]}::\n"); 416 push(@out,"$label{$_[0]}::\n");
354 } 417 }
418 elsif ($label{$_[0]} !~ /^\$/)
419 {
420 push(@out,"$label{$_[0]}\tLABEL PTR\n");
421 }
355 else 422 else
356 { 423 {
357 push(@out,"$label{$_[0]}:\n"); 424 push(@out,"$label{$_[0]}:\n");
358 } 425 }
359 } 426 }
360 427
428sub main'data_byte
429 {
430 push(@out,"\tDB\t".join(',',@_)."\n");
431 }
432
361sub main'data_word 433sub main'data_word
362 { 434 {
363 push(@out,"\tDD\t$_[0]\n"); 435 push(@out,"\tDD\t".join(',',@_)."\n");
436 }
437
438sub main'align
439 {
440 push(@out,"\tALIGN\t$_[0]\n");
364 } 441 }
365 442
366sub out1p 443sub out1p
@@ -368,7 +445,7 @@ sub out1p
368 local($name,$p1)=@_; 445 local($name,$p1)=@_;
369 local($l,$t); 446 local($l,$t);
370 447
371 push(@out,"\t$name\t ".&conv($p1)."\n"); 448 push(@out,"\t$name\t".&conv($p1)."\n");
372 } 449 }
373 450
374sub main'picmeup 451sub main'picmeup
@@ -378,3 +455,18 @@ sub main'picmeup
378 } 455 }
379 456
380sub main'blindpop { &out1("pop",@_); } 457sub main'blindpop { &out1("pop",@_); }
458
459sub main'initseg
460 {
461 local($f)=@_;
462 local($tmp)=<<___;
463OPTION DOTNAME
464.CRT\$XCU SEGMENT DWORD PUBLIC 'DATA'
465EXTRN _$f:NEAR
466DD _$f
467.CRT\$XCU ENDS
468___
469 push(@out,$tmp);
470 }
471
4721;
diff --git a/src/lib/libcrypto/perlasm/x86nasm.pl b/src/lib/libcrypto/perlasm/x86nasm.pl
index 4bdb3fe180..fa38f89c09 100644
--- a/src/lib/libcrypto/perlasm/x86nasm.pl
+++ b/src/lib/libcrypto/perlasm/x86nasm.pl
@@ -3,6 +3,7 @@
3package x86nasm; 3package x86nasm;
4 4
5$label="L000"; 5$label="L000";
6$under=($main'netware)?'':'_';
6 7
7%lb=( 'eax', 'al', 8%lb=( 'eax', 'al',
8 'ebx', 'bl', 9 'ebx', 'bl',
@@ -32,7 +33,8 @@ sub main'external_label
32{ 33{
33 push(@labels,@_); 34 push(@labels,@_);
34 foreach (@_) { 35 foreach (@_) {
35 push(@out, "extern\t_$_\n"); 36 push(@out,".") if ($main'mwerks);
37 push(@out, "extern\t${under}$_\n");
36 } 38 }
37} 39}
38 40
@@ -58,14 +60,19 @@ sub main'DWP
58 &get_mem("DWORD",@_); 60 &get_mem("DWORD",@_);
59 } 61 }
60 62
63sub main'QWP
64 {
65 &get_mem("",@_);
66 }
67
61sub main'BC 68sub main'BC
62 { 69 {
63 return "BYTE @_"; 70 return (($main'mwerks)?"":"BYTE ")."@_";
64 } 71 }
65 72
66sub main'DWC 73sub main'DWC
67 { 74 {
68 return "DWORD @_"; 75 return (($main'mwerks)?"":"DWORD ")."@_";
69 } 76 }
70 77
71sub main'stack_push 78sub main'stack_push
@@ -86,16 +93,22 @@ sub get_mem
86 { 93 {
87 my($size,$addr,$reg1,$reg2,$idx)=@_; 94 my($size,$addr,$reg1,$reg2,$idx)=@_;
88 my($t,$post); 95 my($t,$post);
89 my($ret)="$size ["; 96 my($ret)=$size;
97 if ($ret ne "")
98 {
99 $ret .= " PTR" if ($main'mwerks);
100 $ret .= " ";
101 }
102 $ret .= "[";
90 $addr =~ s/^\s+//; 103 $addr =~ s/^\s+//;
91 if ($addr =~ /^(.+)\+(.+)$/) 104 if ($addr =~ /^(.+)\+(.+)$/)
92 { 105 {
93 $reg2=&conv($1); 106 $reg2=&conv($1);
94 $addr="_$2"; 107 $addr="$under$2";
95 } 108 }
96 elsif ($addr =~ /^[_a-zA-Z]/) 109 elsif ($addr =~ /^[_a-z][_a-z0-9]*$/i)
97 { 110 {
98 $addr="_$addr"; 111 $addr="$under$addr";
99 } 112 }
100 113
101 if ($addr =~ /^.+\-.+$/) { $addr="($addr)"; } 114 if ($addr =~ /^.+\-.+$/) { $addr="($addr)"; }
@@ -134,12 +147,14 @@ sub main'xorb { &out2("xor",@_); }
134sub main'add { &out2("add",@_); } 147sub main'add { &out2("add",@_); }
135sub main'adc { &out2("adc",@_); } 148sub main'adc { &out2("adc",@_); }
136sub main'sub { &out2("sub",@_); } 149sub main'sub { &out2("sub",@_); }
150sub main'sbb { &out2("sbb",@_); }
137sub main'rotl { &out2("rol",@_); } 151sub main'rotl { &out2("rol",@_); }
138sub main'rotr { &out2("ror",@_); } 152sub main'rotr { &out2("ror",@_); }
139sub main'exch { &out2("xchg",@_); } 153sub main'exch { &out2("xchg",@_); }
140sub main'cmp { &out2("cmp",@_); } 154sub main'cmp { &out2("cmp",@_); }
141sub main'lea { &out2("lea",@_); } 155sub main'lea { &out2("lea",@_); }
142sub main'mul { &out1("mul",@_); } 156sub main'mul { &out1("mul",@_); }
157sub main'imul { &out2("imul",@_); }
143sub main'div { &out1("div",@_); } 158sub main'div { &out1("div",@_); }
144sub main'dec { &out1("dec",@_); } 159sub main'dec { &out1("dec",@_); }
145sub main'inc { &out1("inc",@_); } 160sub main'inc { &out1("inc",@_); }
@@ -147,29 +162,57 @@ sub main'jmp { &out1("jmp",@_); }
147sub main'jmp_ptr { &out1p("jmp",@_); } 162sub main'jmp_ptr { &out1p("jmp",@_); }
148 163
149# This is a bit of a kludge: declare all branches as NEAR. 164# This is a bit of a kludge: declare all branches as NEAR.
150sub main'je { &out1("je NEAR",@_); } 165$near=($main'mwerks)?'':'NEAR';
151sub main'jle { &out1("jle NEAR",@_); } 166sub main'je { &out1("je $near",@_); }
152sub main'jz { &out1("jz NEAR",@_); } 167sub main'jle { &out1("jle $near",@_); }
153sub main'jge { &out1("jge NEAR",@_); } 168sub main'jz { &out1("jz $near",@_); }
154sub main'jl { &out1("jl NEAR",@_); } 169sub main'jge { &out1("jge $near",@_); }
155sub main'ja { &out1("ja NEAR",@_); } 170sub main'jl { &out1("jl $near",@_); }
156sub main'jae { &out1("jae NEAR",@_); } 171sub main'ja { &out1("ja $near",@_); }
157sub main'jb { &out1("jb NEAR",@_); } 172sub main'jae { &out1("jae $near",@_); }
158sub main'jbe { &out1("jbe NEAR",@_); } 173sub main'jb { &out1("jb $near",@_); }
159sub main'jc { &out1("jc NEAR",@_); } 174sub main'jbe { &out1("jbe $near",@_); }
160sub main'jnc { &out1("jnc NEAR",@_); } 175sub main'jc { &out1("jc $near",@_); }
161sub main'jnz { &out1("jnz NEAR",@_); } 176sub main'jnc { &out1("jnc $near",@_); }
162sub main'jne { &out1("jne NEAR",@_); } 177sub main'jnz { &out1("jnz $near",@_); }
163sub main'jno { &out1("jno NEAR",@_); } 178sub main'jne { &out1("jne $near",@_); }
179sub main'jno { &out1("jno $near",@_); }
164 180
165sub main'push { &out1("push",@_); $stack+=4; } 181sub main'push { &out1("push",@_); $stack+=4; }
166sub main'pop { &out1("pop",@_); $stack-=4; } 182sub main'pop { &out1("pop",@_); $stack-=4; }
183sub main'pushf { &out0("pushfd"); $stack+=4; }
184sub main'popf { &out0("popfd"); $stack-=4; }
167sub main'bswap { &out1("bswap",@_); &using486(); } 185sub main'bswap { &out1("bswap",@_); &using486(); }
168sub main'not { &out1("not",@_); } 186sub main'not { &out1("not",@_); }
169sub main'call { &out1("call",($_[0]=~/^\$L/?'':'_').$_[0]); } 187sub main'call { &out1("call",($_[0]=~/^\@L/?'':$under).$_[0]); }
188sub main'call_ptr { &out1p("call",@_); }
170sub main'ret { &out0("ret"); } 189sub main'ret { &out0("ret"); }
171sub main'nop { &out0("nop"); } 190sub main'nop { &out0("nop"); }
191sub main'test { &out2("test",@_); }
192sub main'bt { &out2("bt",@_); }
193sub main'leave { &out0("leave"); }
194sub main'cpuid { &out0("cpuid"); }
195sub main'rdtsc { &out0("rdtsc"); }
196sub main'halt { &out0("hlt"); }
172sub main'movz { &out2("movzx",@_); } 197sub main'movz { &out2("movzx",@_); }
198sub main'neg { &out1("neg",@_); }
199sub main'cld { &out0("cld"); }
200
201# SSE2
202sub main'emms { &out0("emms"); }
203sub main'movd { &out2("movd",@_); }
204sub main'movq { &out2("movq",@_); }
205sub main'movdqu { &out2("movdqu",@_); }
206sub main'movdqa { &out2("movdqa",@_); }
207sub main'movdq2q{ &out2("movdq2q",@_); }
208sub main'movq2dq{ &out2("movq2dq",@_); }
209sub main'paddq { &out2("paddq",@_); }
210sub main'pmuludq{ &out2("pmuludq",@_); }
211sub main'psrlq { &out2("psrlq",@_); }
212sub main'psllq { &out2("psllq",@_); }
213sub main'pxor { &out2("pxor",@_); }
214sub main'por { &out2("por",@_); }
215sub main'pand { &out2("pand",@_); }
173 216
174sub out2 217sub out2
175 { 218 {
@@ -177,7 +220,7 @@ sub out2
177 my($l,$t); 220 my($l,$t);
178 221
179 push(@out,"\t$name\t"); 222 push(@out,"\t$name\t");
180 if ($name eq "lea") 223 if (!$main'mwerks and $name eq "lea")
181 { 224 {
182 $p1 =~ s/^[^\[]*\[/\[/; 225 $p1 =~ s/^[^\[]*\[/\[/;
183 $p2 =~ s/^[^\[]*\[/\[/; 226 $p2 =~ s/^[^\[]*\[/\[/;
@@ -221,15 +264,17 @@ sub using486
221 264
222sub main'file 265sub main'file
223 { 266 {
224 local $tmp; 267 if ($main'mwerks) { push(@out,".section\t.text\n"); }
225 $tmp=<<___; 268 else {
269 local $tmp=<<___;
226%ifdef __omf__ 270%ifdef __omf__
227section code use32 class=code 271section code use32 class=code
228%else 272%else
229section .text 273section .text
230%endif 274%endif
231___ 275___
232 push(@out,$tmp); 276 push(@out,$tmp);
277 }
233 } 278 }
234 279
235sub main'function_begin 280sub main'function_begin
@@ -237,9 +282,10 @@ sub main'function_begin
237 my($func,$extra)=@_; 282 my($func,$extra)=@_;
238 283
239 push(@labels,$func); 284 push(@labels,$func);
285 push(@out,".") if ($main'mwerks);
240 my($tmp)=<<"EOF"; 286 my($tmp)=<<"EOF";
241global _$func 287global $under$func
242_$func: 288$under$func:
243 push ebp 289 push ebp
244 push ebx 290 push ebx
245 push esi 291 push esi
@@ -252,9 +298,10 @@ EOF
252sub main'function_begin_B 298sub main'function_begin_B
253 { 299 {
254 my($func,$extra)=@_; 300 my($func,$extra)=@_;
301 push(@out,".") if ($main'mwerks);
255 my($tmp)=<<"EOF"; 302 my($tmp)=<<"EOF";
256global _$func 303global $under$func
257_$func: 304$under$func:
258EOF 305EOF
259 push(@out,$tmp); 306 push(@out,$tmp);
260 $stack=4; 307 $stack=4;
@@ -328,11 +375,18 @@ sub main'comment
328 } 375 }
329 } 376 }
330 377
378sub main'public_label
379 {
380 $label{$_[0]}="${under}${_[0]}" if (!defined($label{$_[0]}));
381 push(@out,".") if ($main'mwerks);
382 push(@out,"global\t$label{$_[0]}\n");
383 }
384
331sub main'label 385sub main'label
332 { 386 {
333 if (!defined($label{$_[0]})) 387 if (!defined($label{$_[0]}))
334 { 388 {
335 $label{$_[0]}="\$${label}${_[0]}"; 389 $label{$_[0]}="\@${label}${_[0]}";
336 $label++; 390 $label++;
337 } 391 }
338 return($label{$_[0]}); 392 return($label{$_[0]});
@@ -342,15 +396,30 @@ sub main'set_label
342 { 396 {
343 if (!defined($label{$_[0]})) 397 if (!defined($label{$_[0]}))
344 { 398 {
345 $label{$_[0]}="\$${label}${_[0]}"; 399 $label{$_[0]}="\@${label}${_[0]}";
346 $label++; 400 $label++;
347 } 401 }
402 if ($_[1]!=0 && $_[1]>1)
403 {
404 main'align($_[1]);
405 }
348 push(@out,"$label{$_[0]}:\n"); 406 push(@out,"$label{$_[0]}:\n");
349 } 407 }
350 408
409sub main'data_byte
410 {
411 push(@out,(($main'mwerks)?".byte\t":"DB\t").join(',',@_)."\n");
412 }
413
351sub main'data_word 414sub main'data_word
352 { 415 {
353 push(@out,"\tDD\t$_[0]\n"); 416 push(@out,(($main'mwerks)?".long\t":"DD\t").join(',',@_)."\n");
417 }
418
419sub main'align
420 {
421 push(@out,".") if ($main'mwerks);
422 push(@out,"align\t$_[0]\n");
354 } 423 }
355 424
356sub out1p 425sub out1p
@@ -358,7 +427,7 @@ sub out1p
358 my($name,$p1)=@_; 427 my($name,$p1)=@_;
359 my($l,$t); 428 my($l,$t);
360 429
361 push(@out,"\t$name\t ".&conv($p1)."\n"); 430 push(@out,"\t$name\t".&conv($p1)."\n");
362 } 431 }
363 432
364sub main'picmeup 433sub main'picmeup
@@ -368,3 +437,19 @@ sub main'picmeup
368 } 437 }
369 438
370sub main'blindpop { &out1("pop",@_); } 439sub main'blindpop { &out1("pop",@_); }
440
441sub main'initseg
442 {
443 local($f)=@_;
444 if ($main'win32)
445 {
446 local($tmp)=<<___;
447segment .CRT\$XCU data
448extern $under$f
449DD $under$f
450___
451 push(@out,$tmp);
452 }
453 }
454
4551;
diff --git a/src/lib/libcrypto/perlasm/x86unix.pl b/src/lib/libcrypto/perlasm/x86unix.pl
index b61425e951..02d72a32bc 100644
--- a/src/lib/libcrypto/perlasm/x86unix.pl
+++ b/src/lib/libcrypto/perlasm/x86unix.pl
@@ -1,14 +1,15 @@
1#!/usr/local/bin/perl 1#!/usr/local/bin/perl
2 2
3package x86unix; 3package x86unix; # GAS actually...
4 4
5$label="L000"; 5$label="L000";
6$const=""; 6$const="";
7$constl=0; 7$constl=0;
8 8
9$align=($main'aout)?"4":"16"; 9$align=($main'aout)?"4":"16";
10$under=($main'aout)?"_":""; 10$under=($main'aout or $main'coff)?"_":"";
11$com_start=($main'sol)?"/":"#"; 11$dot=($main'aout)?"":".";
12$com_start="#" if ($main'aout or $main'coff);
12 13
13sub main'asm_init_output { @out=(); } 14sub main'asm_init_output { @out=(); }
14sub main'asm_get_output { return(@out); } 15sub main'asm_get_output { return(@out); }
@@ -57,6 +58,24 @@ if ($main'cpp)
57 'edi', '%edi', 58 'edi', '%edi',
58 'ebp', '%ebp', 59 'ebp', '%ebp',
59 'esp', '%esp', 60 'esp', '%esp',
61
62 'mm0', '%mm0',
63 'mm1', '%mm1',
64 'mm2', '%mm2',
65 'mm3', '%mm3',
66 'mm4', '%mm4',
67 'mm5', '%mm5',
68 'mm6', '%mm6',
69 'mm7', '%mm7',
70
71 'xmm0', '%xmm0',
72 'xmm1', '%xmm1',
73 'xmm2', '%xmm2',
74 'xmm3', '%xmm3',
75 'xmm4', '%xmm4',
76 'xmm5', '%xmm5',
77 'xmm6', '%xmm6',
78 'xmm7', '%xmm7',
60 ); 79 );
61 80
62%reg_val=( 81%reg_val=(
@@ -103,6 +122,11 @@ sub main'DWP
103 return($ret); 122 return($ret);
104 } 123 }
105 124
125sub main'QWP
126 {
127 return(&main'DWP(@_));
128 }
129
106sub main'BP 130sub main'BP
107 { 131 {
108 return(&main'DWP(@_)); 132 return(&main'DWP(@_));
@@ -146,12 +170,14 @@ sub main'xorb { &out2("xorb",@_); }
146sub main'add { &out2($_[0]=~/%[a-d][lh]/?"addb":"addl",@_); } 170sub main'add { &out2($_[0]=~/%[a-d][lh]/?"addb":"addl",@_); }
147sub main'adc { &out2("adcl",@_); } 171sub main'adc { &out2("adcl",@_); }
148sub main'sub { &out2("subl",@_); } 172sub main'sub { &out2("subl",@_); }
173sub main'sbb { &out2("sbbl",@_); }
149sub main'rotl { &out2("roll",@_); } 174sub main'rotl { &out2("roll",@_); }
150sub main'rotr { &out2("rorl",@_); } 175sub main'rotr { &out2("rorl",@_); }
151sub main'exch { &out2($_[0]=~/%[a-d][lh]/?"xchgb":"xchgl",@_); } 176sub main'exch { &out2($_[0]=~/%[a-d][lh]/?"xchgb":"xchgl",@_); }
152sub main'cmp { &out2("cmpl",@_); } 177sub main'cmp { &out2("cmpl",@_); }
153sub main'lea { &out2("leal",@_); } 178sub main'lea { &out2("leal",@_); }
154sub main'mul { &out1("mull",@_); } 179sub main'mul { &out1("mull",@_); }
180sub main'imul { &out2("imull",@_); }
155sub main'div { &out1("divl",@_); } 181sub main'div { &out1("divl",@_); }
156sub main'jmp { &out1("jmp",@_); } 182sub main'jmp { &out1("jmp",@_); }
157sub main'jmp_ptr { &out1p("jmp",@_); } 183sub main'jmp_ptr { &out1p("jmp",@_); }
@@ -173,15 +199,48 @@ sub main'dec { &out1("decl",@_); }
173sub main'inc { &out1($_[0]=~/%[a-d][hl]/?"incb":"incl",@_); } 199sub main'inc { &out1($_[0]=~/%[a-d][hl]/?"incb":"incl",@_); }
174sub main'push { &out1("pushl",@_); $stack+=4; } 200sub main'push { &out1("pushl",@_); $stack+=4; }
175sub main'pop { &out1("popl",@_); $stack-=4; } 201sub main'pop { &out1("popl",@_); $stack-=4; }
176sub main'pushf { &out0("pushf"); $stack+=4; } 202sub main'pushf { &out0("pushfl"); $stack+=4; }
177sub main'popf { &out0("popf"); $stack-=4; } 203sub main'popf { &out0("popfl"); $stack-=4; }
178sub main'not { &out1("notl",@_); } 204sub main'not { &out1("notl",@_); }
179sub main'call { &out1("call",($_[0]=~/^\.L/?'':$under).$_[0]); } 205sub main'call { my $pre=$under;
206 foreach $i (%label)
207 { if ($label{$i} eq $_[0]) { $pre=''; last; } }
208 &out1("call",$pre.$_[0]);
209 }
210sub main'call_ptr { &out1p("call",@_); }
180sub main'ret { &out0("ret"); } 211sub main'ret { &out0("ret"); }
181sub main'nop { &out0("nop"); } 212sub main'nop { &out0("nop"); }
182sub main'test { &out2("testl",@_); } 213sub main'test { &out2("testl",@_); }
214sub main'bt { &out2("btl",@_); }
215sub main'leave { &out0("leave"); }
216sub main'cpuid { &out0(".byte\t0x0f,0xa2"); }
217sub main'rdtsc { &out0(".byte\t0x0f,0x31"); }
218sub main'halt { &out0("hlt"); }
183sub main'movz { &out2("movzbl",@_); } 219sub main'movz { &out2("movzbl",@_); }
184sub main'neg { &out1("negl",@_); } 220sub main'neg { &out1("negl",@_); }
221sub main'cld { &out0("cld"); }
222
223# SSE2
224sub main'emms { &out0("emms"); }
225sub main'movd { &out2("movd",@_); }
226sub main'movdqu { &out2("movdqu",@_); }
227sub main'movdqa { &out2("movdqa",@_); }
228sub main'movdq2q{ &out2("movdq2q",@_); }
229sub main'movq2dq{ &out2("movq2dq",@_); }
230sub main'paddq { &out2("paddq",@_); }
231sub main'pmuludq{ &out2("pmuludq",@_); }
232sub main'psrlq { &out2("psrlq",@_); }
233sub main'psllq { &out2("psllq",@_); }
234sub main'pxor { &out2("pxor",@_); }
235sub main'por { &out2("por",@_); }
236sub main'pand { &out2("pand",@_); }
237sub main'movq {
238 local($p1,$p2,$optimize)=@_;
239 if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/)
240 # movq between mmx registers can sink Intel CPUs
241 { push(@out,"\tpshufw\t\$0xe4,%$p2,%$p1\n"); }
242 else { &out2("movq",@_); }
243 }
185 244
186# The bswapl instruction is new for the 486. Emulate if i386. 245# The bswapl instruction is new for the 486. Emulate if i386.
187sub main'bswap 246sub main'bswap
@@ -290,8 +349,6 @@ sub main'file
290 349
291 local($tmp)=<<"EOF"; 350 local($tmp)=<<"EOF";
292 .file "$file.s" 351 .file "$file.s"
293 .version "01.01"
294gcc2_compiled.:
295EOF 352EOF
296 push(@out,$tmp); 353 push(@out,$tmp);
297 } 354 }
@@ -308,15 +365,17 @@ sub main'function_begin
308 365
309 local($tmp)=<<"EOF"; 366 local($tmp)=<<"EOF";
310.text 367.text
311 .align $align 368.globl $func
312.globl $func
313EOF 369EOF
314 push(@out,$tmp); 370 push(@out,$tmp);
315 if ($main'cpp) 371 if ($main'cpp)
316 { $tmp=push(@out,"\tTYPE($func,\@function)\n"); } 372 { $tmp=push(@out,"TYPE($func,\@function)\n"); }
317 elsif ($main'gaswin) 373 elsif ($main'coff)
318 { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } 374 { $tmp=push(@out,".def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
319 else { $tmp=push(@out,"\t.type\t$func,\@function\n"); } 375 elsif ($main'aout and !$main'pic)
376 { }
377 else { $tmp=push(@out,".type\t$func,\@function\n"); }
378 push(@out,".align\t$align\n");
320 push(@out,"$func:\n"); 379 push(@out,"$func:\n");
321skip: 380skip:
322 $tmp=<<"EOF"; 381 $tmp=<<"EOF";
@@ -342,15 +401,17 @@ sub main'function_begin_B
342 401
343 local($tmp)=<<"EOF"; 402 local($tmp)=<<"EOF";
344.text 403.text
345 .align $align 404.globl $func
346.globl $func
347EOF 405EOF
348 push(@out,$tmp); 406 push(@out,$tmp);
349 if ($main'cpp) 407 if ($main'cpp)
350 { push(@out,"\tTYPE($func,\@function)\n"); } 408 { push(@out,"TYPE($func,\@function)\n"); }
351 elsif ($main'gaswin) 409 elsif ($main'coff)
352 { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } 410 { $tmp=push(@out,".def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
353 else { push(@out,"\t.type $func,\@function\n"); } 411 elsif ($main'aout and !$main'pic)
412 { }
413 else { push(@out,".type $func,\@function\n"); }
414 push(@out,".align\t$align\n");
354 push(@out,"$func:\n"); 415 push(@out,"$func:\n");
355skip: 416skip:
356 $stack=4; 417 $stack=4;
@@ -368,15 +429,15 @@ sub main'function_end
368 popl %ebx 429 popl %ebx
369 popl %ebp 430 popl %ebp
370 ret 431 ret
371.L_${func}_end: 432${dot}L_${func}_end:
372EOF 433EOF
373 push(@out,$tmp); 434 push(@out,$tmp);
374 435
375 if ($main'cpp) 436 if ($main'cpp)
376 { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); } 437 { push(@out,"SIZE($func,${dot}L_${func}_end-$func)\n"); }
377 elsif ($main'gaswin) 438 elsif ($main'coff or $main'aout)
378 { $tmp=push(@out,"\t.align 4\n"); } 439 { }
379 else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); } 440 else { push(@out,".size\t$func,${dot}L_${func}_end-$func\n"); }
380 push(@out,".ident \"$func\"\n"); 441 push(@out,".ident \"$func\"\n");
381 $stack=0; 442 $stack=0;
382 %label=(); 443 %label=();
@@ -402,13 +463,13 @@ sub main'function_end_B
402 463
403 $func=$under.$func; 464 $func=$under.$func;
404 465
405 push(@out,".L_${func}_end:\n"); 466 push(@out,"${dot}L_${func}_end:\n");
406 if ($main'cpp) 467 if ($main'cpp)
407 { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); } 468 { push(@out,"SIZE($func,${dot}L_${func}_end-$func)\n"); }
408 elsif ($main'gaswin) 469 elsif ($main'coff or $main'aout)
409 { push(@out,"\t.align 4\n"); } 470 { }
410 else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); } 471 else { push(@out,".size\t$func,${dot}L_${func}_end-$func\n"); }
411 push(@out,".ident \"desasm.pl\"\n"); 472 push(@out,".ident \"$func\"\n");
412 $stack=0; 473 $stack=0;
413 %label=(); 474 %label=();
414 } 475 }
@@ -449,10 +510,10 @@ sub main'swtmp
449 510
450sub main'comment 511sub main'comment
451 { 512 {
452 if (!$main'openbsd && $main'elf) 513 if (!defined($com_start) or $main'elf)
514 { # Regarding $main'elf above...
453 # GNU and SVR4 as'es use different comment delimiters, 515 # GNU and SVR4 as'es use different comment delimiters,
454 { # so we just skip comments... 516 push(@out,"\n"); # so we just skip ELF comments...
455 push(@out,"\n");
456 return; 517 return;
457 } 518 }
458 foreach (@_) 519 foreach (@_)
@@ -465,16 +526,16 @@ sub main'comment
465 } 526 }
466 527
467sub main'public_label 528sub main'public_label
468 { 529 {
469 $label{$_[0]}="${under}${_[0]}" if (!defined($label{$_[0]})); 530 $label{$_[0]}="${under}${_[0]}" if (!defined($label{$_[0]}));
470 push(@out,".globl\t$label{$_[0]}\n"); 531 push(@out,".globl\t$label{$_[0]}\n");
471 } 532 }
472 533
473sub main'label 534sub main'label
474 { 535 {
475 if (!defined($label{$_[0]})) 536 if (!defined($label{$_[0]}))
476 { 537 {
477 $label{$_[0]}=".${label}${_[0]}"; 538 $label{$_[0]}="${dot}${label}${_[0]}";
478 $label++; 539 $label++;
479 } 540 }
480 return($label{$_[0]}); 541 return($label{$_[0]});
@@ -484,18 +545,35 @@ sub main'set_label
484 { 545 {
485 if (!defined($label{$_[0]})) 546 if (!defined($label{$_[0]}))
486 { 547 {
487 $label{$_[0]}=".${label}${_[0]}"; 548 $label{$_[0]}="${dot}${label}${_[0]}";
488 $label++; 549 $label++;
489 } 550 }
490 if ($main'openbsd) 551 if ($_[1]!=0)
491 { push(@out,"_ALIGN_TEXT\n") if ($_[1] != 0); } 552 {
492 else 553 if ($_[1]>1) { main'align($_[1]); }
493 { push(@out,".align $align\n") if ($_[1] != 0); } 554 else
555 {
556 if ($main'openbsd)
557 { push(@out,"_ALIGN_TEXT\n"); }
558 else
559 { push(@out,".align $align\n"); }
560 }
561 }
494 push(@out,"$label{$_[0]}:\n"); 562 push(@out,"$label{$_[0]}:\n");
495 } 563 }
496 564
497sub main'file_end 565sub main'file_end
498 { 566 {
567 # try to detect if SSE2 or MMX extensions were used on ELF platform...
568 if ($main'elf && grep {/\b%[x]*mm[0-7]\b|OPENSSL_ia32cap_P\b/i} @out) {
569 local($tmp);
570
571 push (@out,"\n.section\t.bss\n");
572 push (@out,".comm\t${under}OPENSSL_ia32cap_P,4,4\n");
573
574 return;
575 }
576
499 if ($const ne "") 577 if ($const ne "")
500 { 578 {
501 push(@out,".section .rodata\n"); 579 push(@out,".section .rodata\n");
@@ -504,11 +582,31 @@ sub main'file_end
504 } 582 }
505 } 583 }
506 584
585sub main'data_byte
586 {
587 push(@out,"\t.byte\t".join(',',@_)."\n");
588 }
589
507sub main'data_word 590sub main'data_word
508 { 591 {
509 push(@out,"\t.long\t".join(',',@_)."\n"); 592 push(@out,"\t.long\t".join(',',@_)."\n");
510 } 593 }
511 594
595sub main'align
596 {
597 my $val=$_[0],$p2,$i;
598 if ($main'aout) {
599 for ($p2=0;$val!=0;$val>>=1) { $p2++; }
600 $val=$p2-1;
601 $val.=",0x90";
602 }
603 push(@out,".align\t$val\n");
604 if ($main'openbsd)
605 { push(@out,"_ALIGN_TEXT\n"); }
606 else
607 { push(@out,".align $tval\n"); }
608 }
609
512# debug output functions: puts, putx, printf 610# debug output functions: puts, putx, printf
513 611
514sub main'puts 612sub main'puts
@@ -588,7 +686,6 @@ sub main'picmeup
588 { 686 {
589 local($tmp)=<<___; 687 local($tmp)=<<___;
590#if (defined(ELF) || defined(SOL)) && defined(PIC) 688#if (defined(ELF) || defined(SOL)) && defined(PIC)
591 .align 8
592 call 1f 689 call 1f
5931: popl $regs{$dst} 6901: popl $regs{$dst}
594 addl \$_GLOBAL_OFFSET_TABLE_+[.-1b],$regs{$dst} 691 addl \$_GLOBAL_OFFSET_TABLE_+[.-1b],$regs{$dst}
@@ -611,13 +708,12 @@ ___
611 } 708 }
612 elsif ($main'pic && ($main'elf || $main'aout)) 709 elsif ($main'pic && ($main'elf || $main'aout))
613 { 710 {
614 push(@out,"\t.align\t8\n");
615 &main'call(&main'label("PIC_me_up")); 711 &main'call(&main'label("PIC_me_up"));
616 &main'set_label("PIC_me_up"); 712 &main'set_label("PIC_me_up");
617 &main'blindpop($dst); 713 &main'blindpop($dst);
618 &main'add($dst,"\$$under"."_GLOBAL_OFFSET_TABLE_+[.-". 714 &main'add($dst,"\$${under}_GLOBAL_OFFSET_TABLE_+[.-".
619 &main'label("PIC_me_up") . "]"); 715 &main'label("PIC_me_up") . "]");
620 &main'mov($dst,&main'DWP($sym."\@GOT",$dst)); 716 &main'mov($dst,&main'DWP($under.$sym."\@GOT",$dst));
621 } 717 }
622 else 718 else
623 { 719 {
@@ -626,3 +722,41 @@ ___
626 } 722 }
627 723
628sub main'blindpop { &out1("popl",@_); } 724sub main'blindpop { &out1("popl",@_); }
725
726sub main'initseg
727 {
728 local($f)=@_;
729 local($tmp);
730 if ($main'elf)
731 {
732 $tmp=<<___;
733.section .init
734 call $under$f
735 jmp .Linitalign
736.align $align
737.Linitalign:
738___
739 }
740 elsif ($main'coff)
741 {
742 $tmp=<<___; # applies to both Cygwin and Mingw
743.section .ctors
744.long $under$f
745___
746 }
747 elsif ($main'aout)
748 {
749 local($ctor)="${under}_GLOBAL_\$I\$$f";
750 $tmp=".text\n";
751 $tmp.=".type $ctor,\@function\n" if ($main'pic);
752 $tmp.=<<___; # OpenBSD way...
753.globl $ctor
754.align 2
755$ctor:
756 jmp $under$f
757___
758 }
759 push(@out,$tmp) if ($tmp);
760 }
761
7621;