51 # .picmeup %rax
52 # lea .Label-.(%rax),%rax
53 #
54 # 8. In order to provide for structured exception handling unified
55 # Win64 prologue copies %rsp value to %rax. For further details
56 # see SEH paragraph at the end.
57 # 9. .init segment is allowed to contain calls to functions only.
58 # a. If function accepts more than 4 arguments *and* >4th argument
59 # is declared as non 64-bit value, do clear its upper part.
60
61 my $flavour = shift;
62 my $output = shift;
63 if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
64
65 open STDOUT,">$output" || die "can't open $output: $!"
66 if (defined($output));
67
68 my $gas=1; $gas=0 if ($output =~ /\.asm$/);
69 my $elf=1; $elf=0 if (!$gas);
70 my $win64=0;
71 my $prefix="";
72 my $decor=".L";
73
74 my $masmref=8 + 50727*2**-32; # 8.00.50727 shipped with VS2005
75 my $masm=0;
76 my $PTR=" PTR";
77
78 my $nasmref=2.03;
79 my $nasm=0;
80
81 if ($flavour eq "mingw64") { $gas=1; $elf=0; $win64=1;
82 $prefix=`echo __USER_LABEL_PREFIX__ | $ENV{CC} -E -P -`;
83 chomp($prefix);
84 }
85 elsif ($flavour eq "macosx") { $gas=1; $elf=0; $prefix="_"; $decor="L\$"; }
86 elsif ($flavour eq "masm") { $gas=0; $elf=0; $masm=$masmref; $win64=1; $decor="\$L\$"; }
87 elsif ($flavour eq "nasm") { $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $decor="\$L\$"; $PTR=""; }
88 elsif (!$gas)
89 { if ($ENV{ASM} =~ m/nasm/ && `nasm -v` =~ m/version ([0-9]+)\.([0-9]+)/i)
90 { $nasm = $1 + $2*0.01; $PTR=""; }
91 elsif (`ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/)
450 };
451 /\.global|\.globl|\.extern/
452 && do { $globals{$line} = $prefix . $line;
453 $line = $globals{$line} if ($prefix);
454 last;
455 };
456 /\.type/ && do { ($sym,$type,$narg) = split(',',$line);
457 if ($type eq "\@function") {
458 undef $current_function;
459 $current_function->{name} = $sym;
460 $current_function->{abi} = "svr4";
461 $current_function->{narg} = $narg;
462 $current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
463 } elsif ($type eq "\@abi-omnipotent") {
464 undef $current_function;
465 $current_function->{name} = $sym;
466 $current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
467 }
468 $line =~ s/\@abi\-omnipotent/\@function/;
469 $line =~ s/\@function.*/\@function/;
470 last;
471 };
472 /\.asciz/ && do { if ($line =~ /^"(.*)"$/) {
473 $dir = ".byte";
474 $line = join(",",unpack("C*",$1),0);
475 }
476 last;
477 };
478 /\.rva|\.long|\.quad/
479 && do { $line =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
480 $line =~ s/\.L/$decor/g;
481 last;
482 };
483 }
484
485 if ($gas) {
486 $self->{value} = $dir . "\t" . $line;
487
488 if ($dir =~ /\.extern/) {
489 $self->{value} = ""; # swallow extern
490 } elsif (!$elf && $dir =~ /\.type/) {
491 $self->{value} = "";
492 $self->{value} = ".def\t" . ($globals{$1} or $1) . ";\t" .
493 (defined($globals{$1})?".scl 2;":".scl 3;") .
494 "\t.type 32;\t.endef"
495 if ($win64 && $line =~ /([^,]+),\@function/);
496 } elsif (!$elf && $dir =~ /\.size/) {
497 $self->{value} = "";
498 if (defined($current_function)) {
499 $self->{value} .= "${decor}SEH_end_$current_function->{name}:"
500 if ($win64 && $current_function->{abi} eq "svr4");
501 undef $current_function;
502 }
503 } elsif (!$elf && $dir =~ /\.align/) {
504 $self->{value} = ".p2align\t" . (log($line)/log(2));
505 } elsif ($dir eq ".section") {
506 $current_segment=$line;
507 if (!$elf && $current_segment eq ".init") {
508 if ($flavour eq "macosx") { $self->{value} = ".mod_init_func"; }
509 elsif ($flavour eq "mingw64") { $self->{value} = ".section\t.ctors"; }
510 }
511 } elsif ($dir =~ /\.(text|data)/) {
512 $current_segment=".$1";
513 } elsif ($dir =~ /\.hidden/) {
514 if ($flavour eq "macosx") { $self->{value} = ".private_extern\t$prefix$line"; }
515 elsif ($flavour eq "mingw64") { $self->{value} = ""; }
516 } elsif ($dir =~ /\.comm/) {
517 $self->{value} = "$dir\t$prefix$line";
518 $self->{value} =~ s|,([0-9]+),([0-9]+)$|",$1,".log($2)/log(2)|e if ($flavour eq "macosx");
519 }
520 $line = "";
521 return $self;
522 }
523
524 # non-gas case or nasm/masm
525 SWITCH: for ($dir) {
526 /\.text/ && do { my $v=undef;
527 if ($nasm) {
528 $v="section .text code align=64\n";
529 } else {
530 $v="$current_segment\tENDS\n" if ($current_segment);
531 $current_segment = ".text\$";
532 $v.="$current_segment\tSEGMENT ";
533 $v.=$masm>=$masmref ? "ALIGN(64)" : "PAGE";
534 $v.=" 'CODE'";
535 }
|
51 # .picmeup %rax
52 # lea .Label-.(%rax),%rax
53 #
54 # 8. In order to provide for structured exception handling unified
55 # Win64 prologue copies %rsp value to %rax. For further details
56 # see SEH paragraph at the end.
57 # 9. .init segment is allowed to contain calls to functions only.
58 # a. If function accepts more than 4 arguments *and* >4th argument
59 # is declared as non 64-bit value, do clear its upper part.
60
61 my $flavour = shift;
62 my $output = shift;
63 if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
64
65 open STDOUT,">$output" || die "can't open $output: $!"
66 if (defined($output));
67
68 my $gas=1; $gas=0 if ($output =~ /\.asm$/);
69 my $elf=1; $elf=0 if (!$gas);
70 my $win64=0;
71 my $prefix="sunw_";
72 my $decor=".L";
73
74 my $masmref=8 + 50727*2**-32; # 8.00.50727 shipped with VS2005
75 my $masm=0;
76 my $PTR=" PTR";
77
78 my $nasmref=2.03;
79 my $nasm=0;
80
81 if ($flavour eq "mingw64") { $gas=1; $elf=0; $win64=1;
82 $prefix=`echo __USER_LABEL_PREFIX__ | $ENV{CC} -E -P -`;
83 chomp($prefix);
84 }
85 elsif ($flavour eq "macosx") { $gas=1; $elf=0; $prefix="_"; $decor="L\$"; }
86 elsif ($flavour eq "masm") { $gas=0; $elf=0; $masm=$masmref; $win64=1; $decor="\$L\$"; }
87 elsif ($flavour eq "nasm") { $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $decor="\$L\$"; $PTR=""; }
88 elsif (!$gas)
89 { if ($ENV{ASM} =~ m/nasm/ && `nasm -v` =~ m/version ([0-9]+)\.([0-9]+)/i)
90 { $nasm = $1 + $2*0.01; $PTR=""; }
91 elsif (`ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/)
450 };
451 /\.global|\.globl|\.extern/
452 && do { $globals{$line} = $prefix . $line;
453 $line = $globals{$line} if ($prefix);
454 last;
455 };
456 /\.type/ && do { ($sym,$type,$narg) = split(',',$line);
457 if ($type eq "\@function") {
458 undef $current_function;
459 $current_function->{name} = $sym;
460 $current_function->{abi} = "svr4";
461 $current_function->{narg} = $narg;
462 $current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
463 } elsif ($type eq "\@abi-omnipotent") {
464 undef $current_function;
465 $current_function->{name} = $sym;
466 $current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
467 }
468 $line =~ s/\@abi\-omnipotent/\@function/;
469 $line =~ s/\@function.*/\@function/;
470 $line =~ s/$sym/$globals{$sym} or $sym/e;
471 last;
472 };
473 /\.asciz/ && do { if ($line =~ /^"(.*)"$/) {
474 $dir = ".byte";
475 $line = join(",",unpack("C*",$1),0);
476 }
477 last;
478 };
479 /\.rva|\.long|\.quad/
480 && do { $line =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
481 $line =~ s/\.L/$decor/g;
482 last;
483 };
484 /\.size/ && do { $line =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
485 last;
486 };
487 }
488
489 if ($gas) {
490 $self->{value} = $dir . "\t" . $line;
491
492 if ($dir =~ /\.extern/) {
493 $self->{value} = ""; # swallow extern
494 } elsif (!$elf && $dir =~ /\.type/) {
495 $self->{value} = "";
496 $self->{value} = ".def\t" . ($globals{$1} or $1) . ";\t" .
497 (defined($globals{$1})?".scl 2;":".scl 3;") .
498 "\t.type 32;\t.endef"
499 if ($win64 && $line =~ /([^,]+),\@function/);
500 } elsif (!$elf && $dir =~ /\.size/) {
501 $self->{value} = "";
502 if (defined($current_function)) {
503 $self->{value} .= "${decor}SEH_end_$current_function->{name}:"
504 if ($win64 && $current_function->{abi} eq "svr4");
505 undef $current_function;
506 }
507 } elsif (!$elf && $dir =~ /\.align/) {
508 $self->{value} = ".p2align\t" . (log($line)/log(2));
509 } elsif ($dir eq ".section") {
510 $current_segment=$line;
511 if (!$elf && $current_segment eq ".init") {
512 if ($flavour eq "macosx") { $self->{value} = ".mod_init_func"; }
513 elsif ($flavour eq "mingw64") { $self->{value} = ".section\t.ctors"; }
514 }
515 } elsif ($dir =~ /\.(text|data)/) {
516 $current_segment=".$1";
517 } elsif ($dir =~ /\.hidden/) {
518 if ($flavour eq "macosx") { $self->{value} = ".private_extern\t$prefix$line"; }
519 elsif ($flavour eq "mingw64") { $self->{value} = ""; }
520 else { $self->{value} = ".hidden\t$prefix$line"; }
521 } elsif ($dir =~ /\.comm/) {
522 $self->{value} = "$dir\t$prefix$line";
523 $self->{value} =~ s|,([0-9]+),([0-9]+)$|",$1,".log($2)/log(2)|e if ($flavour eq "macosx");
524 }
525 $line = "";
526 return $self;
527 }
528
529 # non-gas case or nasm/masm
530 SWITCH: for ($dir) {
531 /\.text/ && do { my $v=undef;
532 if ($nasm) {
533 $v="section .text code align=64\n";
534 } else {
535 $v="$current_segment\tENDS\n" if ($current_segment);
536 $current_segment = ".text\$";
537 $v.="$current_segment\tSEGMENT ";
538 $v.=$masm>=$masmref ? "ALIGN(64)" : "PAGE";
539 $v.=" 'CODE'";
540 }
|