#!/usr/bin/env perl

package x86gas;

*out=\@::out;

$::lbdecor=$::aout?"L":".L";		# local label decoration
$nmdecor=($::aout or $::coff)?"_":"";	# external name decoration

$initseg="";

$align=16;
$align=log($align)/log(2) if ($::aout);
$com_start="#" if ($::aout or $::coff);

sub opsize()
{ my $reg=shift;
    if    ($reg =~ m/^%e/o)		{ "l"; }
    elsif ($reg =~ m/^%[a-d][hl]$/o)	{ "b"; }
    elsif ($reg =~ m/^%[yxm]/o)		{ undef; }
    else				{ "w"; }
}

# swap arguments;
# expand opcode with size suffix;
# prefix numeric constants with $;
sub ::generic
{ my($opcode,@arg)=@_;
  my($suffix,$dst,$src);

    @arg=reverse(@arg);

    for (@arg)
    {	s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o;	# gp registers
	s/^([xy]?mm[0-7])$/%$1/o;		# xmm/mmx registers
	s/^(\-?[0-9]+)$/\$$1/o;			# constants
	s/^(\-?0x[0-9a-f]+)$/\$$1/o;		# constants
    }

    $dst = $arg[$#arg]		if ($#arg>=0);
    $src = $arg[$#arg-1]	if ($#arg>=1);
    if    ($dst =~ m/^%/o)	{ $suffix=&opsize($dst); }
    elsif ($src =~ m/^%/o)	{ $suffix=&opsize($src); }
    else			{ $suffix="l";           }
    undef $suffix if ($dst =~ m/^%[xm]/o || $src =~ m/^%[xm]/o);

    if ($#_==0)				{ &::emit($opcode);		}
    elsif ($#_==1 && $opcode =~ m/^(call|clflush|j|loop|set)/o)
					{ &::emit($opcode,@arg);	}
    else				{ &::emit($opcode.$suffix,@arg);}

  1;
}
#
# opcodes not covered by ::generic above, mostly inconsistent namings...
#
sub ::movzx	{ &::movzb(@_);			}
sub ::pushfd	{ &::pushfl;			}
sub ::popfd	{ &::popfl;			}
sub ::cpuid	{ &::emit(".byte\t0x0f,0xa2");	}
sub ::rdtsc	{ &::emit(".byte\t0x0f,0x31");	}

sub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
sub ::call_ptr	{ &::generic("call","*$_[0]");	}
sub ::jmp_ptr	{ &::generic("jmp","*$_[0]");	}

*::bswap = sub	{ &::emit("bswap","%$_[0]");	} if (!$::i386);

sub ::DWP
{ my($addr,$reg1,$reg2,$idx)=@_;
  my $ret="";

    if (!defined($idx) && 1*$reg2) { $idx=$reg2; $reg2=$reg1; undef $reg1; }

    $addr =~ s/^\s+//;
    # prepend global references with optional underscore
    $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige;

    $reg1 = "%$reg1" if ($reg1);
    $reg2 = "%$reg2" if ($reg2);

    $ret .= $addr if (($addr ne "") && ($addr ne 0));

    if ($reg2)
    {	$idx!= 0 or $idx=1;
	$ret .= "($reg1,$reg2,$idx)";
    }
    elsif ($reg1)
    {	$ret .= "($reg1)";	}

  $ret;
}
sub ::QWP	{ &::DWP(@_);	}
sub ::BP	{ &::DWP(@_);	}
sub ::WP	{ &::DWP(@_);	}
sub ::BC	{ @_;		}
sub ::DWC	{ @_;		}

sub ::file
{   push(@out,".file\t\"$_[0].S\"\n.text\n");	}

sub ::function_begin_B
{ my $func=shift;
  my $global=($func !~ /^_/);
  my $begin="${::lbdecor}_${func}_begin";

    &::LABEL($func,$global?"$begin":"$nmdecor$func");
    $func=$nmdecor.$func;

    push(@out,".globl\t$func\n")	if ($global);
    if ($::macosx) {
      push(@out,".private_extern\t$func\n");
    } else {
      push(@out,".hidden\t$func\n");
    }
    if ($::coff)
    {	push(@out,".def\t$func;\t.scl\t".(3-$global).";\t.type\t32;\t.endef\n"); }
    elsif (($::aout and !$::pic) or $::macosx)
    { }
    else
    {	push(@out,".type	$func,\@function\n"); }
    push(@out,".align\t$align\n");
    push(@out,"$func:\n");
    push(@out,"$begin:\n")		if ($global);
    $::stack=4;
}

sub ::function_end_B
{ my $func=shift;
    push(@out,".size\t$nmdecor$func,.-".&::LABEL($func)."\n") if ($::elf);
    $::stack=0;
    &::wipe_labels();
}

sub ::comment
	{
	if (!defined($com_start) or $::elf)
		{	# Regarding $::elf above...
			# GNU and SVR4 as'es use different comment delimiters,
		push(@out,"\n");	# so we just skip ELF comments...
		return;
		}
	foreach (@_)
		{
		if (/^\s*$/)
			{ push(@out,"\n"); }
		else
			{ push(@out,"\t$com_start $_ $com_end\n"); }
		}
	}

sub ::external_label
{   foreach(@_) { &::LABEL($_,$nmdecor.$_); }   }

sub ::public_label
{   push(@out,".globl\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");   }

sub ::file_end
{   if ($::macosx)
    {	if (%non_lazy_ptr)
    	{   push(@out,".section __IMPORT,__pointers,non_lazy_symbol_pointers\n");
	    foreach $i (keys %non_lazy_ptr)
	    {	push(@out,"$non_lazy_ptr{$i}:\n.indirect_symbol\t$i\n.long\t0\n");   }
	}
    }
    if (0 && grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
	my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,16";
	if ($::macosx)	{ push (@out,"$tmp,2\n"); }
	elsif ($::elf)	{ push (@out,"$tmp,4\n"); }
	else		{ push (@out,"$tmp\n"); }
    }
    push(@out,$initseg) if ($initseg);
}

sub ::data_byte	{   push(@out,".byte\t".join(',',@_)."\n");   }
sub ::data_short{   push(@out,".value\t".join(',',@_)."\n");  }
sub ::data_word {   push(@out,".long\t".join(',',@_)."\n");   }

sub ::align
{ my $val=$_[0];
    if ($::aout)
    {	$val=int(log($val)/log(2));
	$val.=",0x90";
    }
    push(@out,".align\t$val\n");
}

sub ::picmeup
{ my($dst,$sym,$base,$reflabel)=@_;

    if (($::pic && ($::elf || $::aout)) || $::macosx)
    {	if (!defined($base))
	{   &::call(&::label("PIC_me_up"));
	    &::set_label("PIC_me_up");
	    &::blindpop($dst);
	    $base=$dst;
	    $reflabel=&::label("PIC_me_up");
	}
	if ($::macosx)
	{   my $indirect=&::static_label("$nmdecor$sym\$non_lazy_ptr");
	    &::mov($dst,&::DWP("$indirect-$reflabel",$base));
	    $non_lazy_ptr{"$nmdecor$sym"}=$indirect;
	}
	elsif ($sym eq "OPENSSL_ia32cap_P" && $::elf>0)
	{   &::lea($dst,&::DWP("$sym-$reflabel",$base));   }
	else
	{   &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]",
			    $base));
	    &::mov($dst,&::DWP("$sym\@GOT",$dst));
	}
    }
    else
    {	&::lea($dst,&::DWP($sym));	}
}

sub ::initseg
{ my $f=$nmdecor.shift;

    if ($::android)
    {	$initseg.=<<___;
.section	.init_array
.align	4
.long	$f
___
    }
    elsif ($::elf)
    {	$initseg.=<<___;
.section	.init
	call	$f
___
    }
    elsif ($::coff)
    {   $initseg.=<<___;	# applies to both Cygwin and Mingw
.section	.ctors
.long	$f
___
    }
    elsif ($::macosx)
    {	$initseg.=<<___;
.mod_init_func
.align 2
.long   $f
___
    }
    elsif ($::aout)
    {	my $ctor="${nmdecor}_GLOBAL_\$I\$$f";
	$initseg.=".text\n";
	$initseg.=".type	$ctor,\@function\n" if ($::pic);
	$initseg.=<<___;	# OpenBSD way...
.globl	$ctor
.align	2
$ctor:
	jmp	$f
___
    }
}

sub ::dataseg
{   push(@out,".data\n");   }

*::hidden = sub { push(@out,".hidden\t$nmdecor$_[0]\n"); } if ($::elf);

1;
