123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- #!/usr/local/bin/perl
- package alpha;
- use Carp qw(croak cluck);
- $label="100";
- $n_debug=0;
- $smear_regs=1;
- $reg_alloc=1;
- $align="3";
- $com_start="#";
- sub main'asm_init_output { @out=(); }
- sub main'asm_get_output { return(@out); }
- sub main'get_labels { return(@labels); }
- sub main'external_label { push(@labels,@_); }
- # General registers
- %regs=( 'r0', '$0',
- 'r1', '$1',
- 'r2', '$2',
- 'r3', '$3',
- 'r4', '$4',
- 'r5', '$5',
- 'r6', '$6',
- 'r7', '$7',
- 'r8', '$8',
- 'r9', '$22',
- 'r10', '$23',
- 'r11', '$24',
- 'r12', '$25',
- 'r13', '$27',
- 'r14', '$28',
- 'r15', '$21', # argc == 5
- 'r16', '$20', # argc == 4
- 'r17', '$19', # argc == 3
- 'r18', '$18', # argc == 2
- 'r19', '$17', # argc == 1
- 'r20', '$16', # argc == 0
- 'r21', '$9', # save 0
- 'r22', '$10', # save 1
- 'r23', '$11', # save 2
- 'r24', '$12', # save 3
- 'r25', '$13', # save 4
- 'r26', '$14', # save 5
- 'a0', '$16',
- 'a1', '$17',
- 'a2', '$18',
- 'a3', '$19',
- 'a4', '$20',
- 'a5', '$21',
- 's0', '$9',
- 's1', '$10',
- 's2', '$11',
- 's3', '$12',
- 's4', '$13',
- 's5', '$14',
- 'zero', '$31',
- 'sp', '$30',
- );
- $main'reg_s0="r21";
- $main'reg_s1="r22";
- $main'reg_s2="r23";
- $main'reg_s3="r24";
- $main'reg_s4="r25";
- $main'reg_s5="r26";
- @reg=( '$0', '$1' ,'$2' ,'$3' ,'$4' ,'$5' ,'$6' ,'$7' ,'$8',
- '$22','$23','$24','$25','$20','$21','$27','$28');
- sub main'sub { &out3("subq",@_); }
- sub main'add { &out3("addq",@_); }
- sub main'mov { &out3("bis",$_[0],$_[0],$_[1]); }
- sub main'or { &out3("bis",@_); }
- sub main'bis { &out3("bis",@_); }
- sub main'br { &out1("br",@_); }
- sub main'ld { &out2("ldq",@_); }
- sub main'st { &out2("stq",@_); }
- sub main'cmpult { &out3("cmpult",@_); }
- sub main'cmplt { &out3("cmplt",@_); }
- sub main'bgt { &out2("bgt",@_); }
- sub main'ble { &out2("ble",@_); }
- sub main'blt { &out2("blt",@_); }
- sub main'mul { &out3("mulq",@_); }
- sub main'muh { &out3("umulh",@_); }
- $main'QWS=8;
- sub main'asm_add
- {
- push(@out,@_);
- }
- sub main'asm_finish
- {
- &main'file_end();
- print &main'asm_get_output();
- }
- sub main'asm_init
- {
- ($type,$fn)=@_;
- $filename=$fn;
- &main'asm_init_output();
- &main'comment("Don't even think of reading this code");
- &main'comment("It was automatically generated by $filename");
- &main'comment("Which is a perl program used to generate the alpha assember.");
- &main'comment("eric <eay\@cryptsoft.com>");
- &main'comment("");
- $filename =~ s/\.pl$//;
- &main'file($filename);
- }
- sub conv
- {
- local($r)=@_;
- local($v);
- return($regs{$r}) if defined($regs{$r});
- return($r);
- }
- sub main'QWPw
- {
- local($off,$reg)=@_;
- return(&main'QWP($off*8,$reg));
- }
- sub main'QWP
- {
- local($off,$reg)=@_;
- $ret="$off(".&conv($reg).")";
- return($ret);
- }
- sub out3
- {
- local($name,$p1,$p2,$p3)=@_;
- $p1=&conv($p1);
- $p2=&conv($p2);
- $p3=&conv($p3);
- push(@out,"\t$name\t");
- $l=length($p1)+1;
- push(@out,$p1.",");
- $ll=3-($l+9)/8;
- $tmp1=sprintf("\t" x $ll);
- push(@out,$tmp1);
- $l=length($p2)+1;
- push(@out,$p2.",");
- $ll=3-($l+9)/8;
- $tmp1=sprintf("\t" x $ll);
- push(@out,$tmp1);
- push(@out,&conv($p3)."\n");
- }
- sub out2
- {
- local($name,$p1,$p2,$p3)=@_;
- $p1=&conv($p1);
- $p2=&conv($p2);
- push(@out,"\t$name\t");
- $l=length($p1)+1;
- push(@out,$p1.",");
- $ll=3-($l+9)/8;
- $tmp1=sprintf("\t" x $ll);
- push(@out,$tmp1);
- push(@out,&conv($p2)."\n");
- }
- sub out1
- {
- local($name,$p1)=@_;
- $p1=&conv($p1);
- push(@out,"\t$name\t".$p1."\n");
- }
- sub out0
- {
- push(@out,"\t$_[0]\n");
- }
- sub main'file
- {
- local($file)=@_;
- local($tmp)=<<"EOF";
- # DEC Alpha assember
- # Generated from perl scripts contains in SSLeay
- .file 1 "$file.s"
- .set noat
- EOF
- push(@out,$tmp);
- }
- sub main'function_begin
- {
- local($func)=@_;
- print STDERR "$func\n";
- local($tmp)=<<"EOF";
- .text
- .align $align
- .globl $func
- .ent $func
- ${func}:
- ${func}..ng:
- .frame \$30,0,\$26,0
- .prologue 0
- EOF
- push(@out,$tmp);
- $stack=0;
- }
- sub main'function_end
- {
- local($func)=@_;
- local($tmp)=<<"EOF";
- ret \$31,(\$26),1
- .end $func
- EOF
- push(@out,$tmp);
- $stack=0;
- %label=();
- }
- sub main'function_end_A
- {
- local($func)=@_;
- local($tmp)=<<"EOF";
- ret \$31,(\$26),1
- EOF
- push(@out,$tmp);
- }
- sub main'function_end_B
- {
- local($func)=@_;
- $func=$under.$func;
- push(@out,"\t.end $func\n");
- $stack=0;
- %label=();
- }
- sub main'wparam
- {
- local($num)=@_;
- if ($num < 6)
- {
- $num=20-$num;
- return("r$num");
- }
- else
- { return(&main'QWP($stack+$num*8,"sp")); }
- }
- sub main'stack_push
- {
- local($num)=@_;
- $stack+=$num*8;
- &main'sub("sp",$num*8,"sp");
- }
- sub main'stack_pop
- {
- local($num)=@_;
- $stack-=$num*8;
- &main'add("sp",$num*8,"sp");
- }
- sub main'swtmp
- {
- return(&main'QWP(($_[0])*8,"sp"));
- }
- # Should use swtmp, which is above sp. Linix can trash the stack above esp
- #sub main'wtmp
- # {
- # local($num)=@_;
- #
- # return(&main'QWP(-($num+1)*4,"esp","",0));
- # }
- sub main'comment
- {
- foreach (@_)
- {
- if (/^\s*$/)
- { push(@out,"\n"); }
- else
- { push(@out,"\t$com_start $_ $com_end\n"); }
- }
- }
- sub main'label
- {
- if (!defined($label{$_[0]}))
- {
- $label{$_[0]}=$label;
- $label++;
- }
- return('$'.$label{$_[0]});
- }
- sub main'set_label
- {
- if (!defined($label{$_[0]}))
- {
- $label{$_[0]}=$label;
- $label++;
- }
- # push(@out,".align $align\n") if ($_[1] != 0);
- push(@out,'$'."$label{$_[0]}:\n");
- }
- sub main'file_end
- {
- }
- sub main'data_word
- {
- push(@out,"\t.long $_[0]\n");
- }
- @pool_free=();
- @pool_taken=();
- $curr_num=0;
- $max=0;
- sub main'init_pool
- {
- local($args)=@_;
- local($i);
- @pool_free=();
- for ($i=(14+(6-$args)); $i >= 0; $i--)
- {
- push(@pool_free,"r$i");
- }
- print STDERR "START :register pool:@pool_free\n";
- $curr_num=$max=0;
- }
- sub main'fin_pool
- {
- printf STDERR "END %2d:register pool:@pool_free\n",$max;
- }
- sub main'GR
- {
- local($r)=@_;
- local($i,@n,$_);
- foreach (@pool_free)
- {
- if ($r ne $_)
- { push(@n,$_); }
- else
- {
- $curr_num++;
- $max=$curr_num if ($curr_num > $max);
- }
- }
- @pool_free=@n;
- print STDERR "GR:@pool_free\n" if $reg_alloc;
- return(@_);
- }
- sub main'NR
- {
- local($num)=@_;
- local(@ret);
- $num=1 if $num == 0;
- ($#pool_free >= ($num-1)) || croak "out of registers: want $num, have @pool_free";
- while ($num > 0)
- {
- push(@ret,pop @pool_free);
- $curr_num++;
- $max=$curr_num if ($curr_num > $max);
- $num--
- }
- print STDERR "nr @ret\n" if $n_debug;
- print STDERR "NR:@pool_free\n" if $reg_alloc;
- return(@ret);
- }
- sub main'FR
- {
- local(@r)=@_;
- local(@a,$v,$w);
- print STDERR "fr @r\n" if $n_debug;
- # cluck "fr @r";
- for $w (@pool_free)
- {
- foreach $v (@r)
- {
- croak "double register free of $v (@pool_free)" if $w eq $v;
- }
- }
- foreach $v (@r)
- {
- croak "bad argument to FR" if ($v !~ /^r\d+$/);
- if ($smear_regs)
- { unshift(@pool_free,$v); }
- else { push(@pool_free,$v); }
- $curr_num--;
- }
- print STDERR "FR:@pool_free\n" if $reg_alloc;
- }
- 1;
|