1*0Sstevel@tonic-gate#!/usr/local/bin/perl 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gatepackage x86unix; 4*0Sstevel@tonic-gate 5*0Sstevel@tonic-gate$label="L000"; 6*0Sstevel@tonic-gate$const=""; 7*0Sstevel@tonic-gate$constl=0; 8*0Sstevel@tonic-gate 9*0Sstevel@tonic-gate$align=($main'aout)?"4":"16"; 10*0Sstevel@tonic-gate$under=($main'aout)?"_":""; 11*0Sstevel@tonic-gate$com_start=($main'sol)?"/":"#"; 12*0Sstevel@tonic-gate 13*0Sstevel@tonic-gatesub main'asm_init_output { @out=(); } 14*0Sstevel@tonic-gatesub main'asm_get_output { return(@out); } 15*0Sstevel@tonic-gatesub main'get_labels { return(@labels); } 16*0Sstevel@tonic-gatesub main'external_label { push(@labels,@_); } 17*0Sstevel@tonic-gate 18*0Sstevel@tonic-gateif ($main'cpp) 19*0Sstevel@tonic-gate { 20*0Sstevel@tonic-gate $align="ALIGN"; 21*0Sstevel@tonic-gate $under=""; 22*0Sstevel@tonic-gate $com_start='/*'; 23*0Sstevel@tonic-gate $com_end='*/'; 24*0Sstevel@tonic-gate } 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate%lb=( 'eax', '%al', 27*0Sstevel@tonic-gate 'ebx', '%bl', 28*0Sstevel@tonic-gate 'ecx', '%cl', 29*0Sstevel@tonic-gate 'edx', '%dl', 30*0Sstevel@tonic-gate 'ax', '%al', 31*0Sstevel@tonic-gate 'bx', '%bl', 32*0Sstevel@tonic-gate 'cx', '%cl', 33*0Sstevel@tonic-gate 'dx', '%dl', 34*0Sstevel@tonic-gate ); 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate%hb=( 'eax', '%ah', 37*0Sstevel@tonic-gate 'ebx', '%bh', 38*0Sstevel@tonic-gate 'ecx', '%ch', 39*0Sstevel@tonic-gate 'edx', '%dh', 40*0Sstevel@tonic-gate 'ax', '%ah', 41*0Sstevel@tonic-gate 'bx', '%bh', 42*0Sstevel@tonic-gate 'cx', '%ch', 43*0Sstevel@tonic-gate 'dx', '%dh', 44*0Sstevel@tonic-gate ); 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate%regs=( 'eax', '%eax', 47*0Sstevel@tonic-gate 'ebx', '%ebx', 48*0Sstevel@tonic-gate 'ecx', '%ecx', 49*0Sstevel@tonic-gate 'edx', '%edx', 50*0Sstevel@tonic-gate 'esi', '%esi', 51*0Sstevel@tonic-gate 'edi', '%edi', 52*0Sstevel@tonic-gate 'ebp', '%ebp', 53*0Sstevel@tonic-gate 'esp', '%esp', 54*0Sstevel@tonic-gate ); 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate%reg_val=( 57*0Sstevel@tonic-gate 'eax', 0x00, 58*0Sstevel@tonic-gate 'ebx', 0x03, 59*0Sstevel@tonic-gate 'ecx', 0x01, 60*0Sstevel@tonic-gate 'edx', 0x02, 61*0Sstevel@tonic-gate 'esi', 0x06, 62*0Sstevel@tonic-gate 'edi', 0x07, 63*0Sstevel@tonic-gate 'ebp', 0x05, 64*0Sstevel@tonic-gate 'esp', 0x04, 65*0Sstevel@tonic-gate ); 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gatesub main'LB 68*0Sstevel@tonic-gate { 69*0Sstevel@tonic-gate (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; 70*0Sstevel@tonic-gate return($lb{$_[0]}); 71*0Sstevel@tonic-gate } 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gatesub main'HB 74*0Sstevel@tonic-gate { 75*0Sstevel@tonic-gate (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; 76*0Sstevel@tonic-gate return($hb{$_[0]}); 77*0Sstevel@tonic-gate } 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gatesub main'DWP 80*0Sstevel@tonic-gate { 81*0Sstevel@tonic-gate local($addr,$reg1,$reg2,$idx)=@_; 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate $ret=""; 84*0Sstevel@tonic-gate $addr =~ s/(^|[+ \t])([A-Za-z_]+[A-Za-z0-9_]+)($|[+ \t])/$1$under$2$3/; 85*0Sstevel@tonic-gate $reg1="$regs{$reg1}" if defined($regs{$reg1}); 86*0Sstevel@tonic-gate $reg2="$regs{$reg2}" if defined($regs{$reg2}); 87*0Sstevel@tonic-gate $ret.=$addr if ($addr ne "") && ($addr ne 0); 88*0Sstevel@tonic-gate if ($reg2 ne "") 89*0Sstevel@tonic-gate { 90*0Sstevel@tonic-gate if($idx ne "" && $idx != 0) 91*0Sstevel@tonic-gate { $ret.="($reg1,$reg2,$idx)"; } 92*0Sstevel@tonic-gate else 93*0Sstevel@tonic-gate { $ret.="($reg1,$reg2)"; } 94*0Sstevel@tonic-gate } 95*0Sstevel@tonic-gate elsif ($reg1 ne "") 96*0Sstevel@tonic-gate { $ret.="($reg1)" } 97*0Sstevel@tonic-gate return($ret); 98*0Sstevel@tonic-gate } 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gatesub main'BP 101*0Sstevel@tonic-gate { 102*0Sstevel@tonic-gate return(&main'DWP(@_)); 103*0Sstevel@tonic-gate } 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gatesub main'BC 106*0Sstevel@tonic-gate { 107*0Sstevel@tonic-gate return @_; 108*0Sstevel@tonic-gate } 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gatesub main'DWC 111*0Sstevel@tonic-gate { 112*0Sstevel@tonic-gate return @_; 113*0Sstevel@tonic-gate } 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate#sub main'BP 116*0Sstevel@tonic-gate# { 117*0Sstevel@tonic-gate# local($addr,$reg1,$reg2,$idx)=@_; 118*0Sstevel@tonic-gate# 119*0Sstevel@tonic-gate# $ret=""; 120*0Sstevel@tonic-gate# 121*0Sstevel@tonic-gate# $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/; 122*0Sstevel@tonic-gate# $reg1="$regs{$reg1}" if defined($regs{$reg1}); 123*0Sstevel@tonic-gate# $reg2="$regs{$reg2}" if defined($regs{$reg2}); 124*0Sstevel@tonic-gate# $ret.=$addr if ($addr ne "") && ($addr ne 0); 125*0Sstevel@tonic-gate# if ($reg2 ne "") 126*0Sstevel@tonic-gate# { $ret.="($reg1,$reg2,$idx)"; } 127*0Sstevel@tonic-gate# else 128*0Sstevel@tonic-gate# { $ret.="($reg1)" } 129*0Sstevel@tonic-gate# return($ret); 130*0Sstevel@tonic-gate# } 131*0Sstevel@tonic-gate 132*0Sstevel@tonic-gatesub main'mov { &out2("movl",@_); } 133*0Sstevel@tonic-gatesub main'movb { &out2("movb",@_); } 134*0Sstevel@tonic-gatesub main'and { &out2("andl",@_); } 135*0Sstevel@tonic-gatesub main'or { &out2("orl",@_); } 136*0Sstevel@tonic-gatesub main'shl { &out2("sall",@_); } 137*0Sstevel@tonic-gatesub main'shr { &out2("shrl",@_); } 138*0Sstevel@tonic-gatesub main'xor { &out2("xorl",@_); } 139*0Sstevel@tonic-gatesub main'xorb { &out2("xorb",@_); } 140*0Sstevel@tonic-gatesub main'add { &out2("addl",@_); } 141*0Sstevel@tonic-gatesub main'adc { &out2("adcl",@_); } 142*0Sstevel@tonic-gatesub main'sub { &out2("subl",@_); } 143*0Sstevel@tonic-gatesub main'rotl { &out2("roll",@_); } 144*0Sstevel@tonic-gatesub main'rotr { &out2("rorl",@_); } 145*0Sstevel@tonic-gatesub main'exch { &out2("xchg",@_); } 146*0Sstevel@tonic-gatesub main'cmp { &out2("cmpl",@_); } 147*0Sstevel@tonic-gatesub main'lea { &out2("leal",@_); } 148*0Sstevel@tonic-gatesub main'mul { &out1("mull",@_); } 149*0Sstevel@tonic-gatesub main'div { &out1("divl",@_); } 150*0Sstevel@tonic-gatesub main'jmp { &out1("jmp",@_); } 151*0Sstevel@tonic-gatesub main'jmp_ptr { &out1p("jmp",@_); } 152*0Sstevel@tonic-gatesub main'je { &out1("je",@_); } 153*0Sstevel@tonic-gatesub main'jle { &out1("jle",@_); } 154*0Sstevel@tonic-gatesub main'jne { &out1("jne",@_); } 155*0Sstevel@tonic-gatesub main'jnz { &out1("jnz",@_); } 156*0Sstevel@tonic-gatesub main'jz { &out1("jz",@_); } 157*0Sstevel@tonic-gatesub main'jge { &out1("jge",@_); } 158*0Sstevel@tonic-gatesub main'jl { &out1("jl",@_); } 159*0Sstevel@tonic-gatesub main'ja { &out1("ja",@_); } 160*0Sstevel@tonic-gatesub main'jae { &out1("jae",@_); } 161*0Sstevel@tonic-gatesub main'jb { &out1("jb",@_); } 162*0Sstevel@tonic-gatesub main'jbe { &out1("jbe",@_); } 163*0Sstevel@tonic-gatesub main'jc { &out1("jc",@_); } 164*0Sstevel@tonic-gatesub main'jnc { &out1("jnc",@_); } 165*0Sstevel@tonic-gatesub main'jno { &out1("jno",@_); } 166*0Sstevel@tonic-gatesub main'dec { &out1("decl",@_); } 167*0Sstevel@tonic-gatesub main'inc { &out1("incl",@_); } 168*0Sstevel@tonic-gatesub main'push { &out1("pushl",@_); $stack+=4; } 169*0Sstevel@tonic-gatesub main'pop { &out1("popl",@_); $stack-=4; } 170*0Sstevel@tonic-gatesub main'pushf { &out0("pushf"); $stack+=4; } 171*0Sstevel@tonic-gatesub main'popf { &out0("popf"); $stack-=4; } 172*0Sstevel@tonic-gatesub main'not { &out1("notl",@_); } 173*0Sstevel@tonic-gatesub main'call { &out1("call",($_[0]=~/^\.L/?'':$under).$_[0]); } 174*0Sstevel@tonic-gatesub main'ret { &out0("ret"); } 175*0Sstevel@tonic-gatesub main'nop { &out0("nop"); } 176*0Sstevel@tonic-gate 177*0Sstevel@tonic-gate# The bswapl instruction is new for the 486. Emulate if i386. 178*0Sstevel@tonic-gatesub main'bswap 179*0Sstevel@tonic-gate { 180*0Sstevel@tonic-gate if ($main'i386) 181*0Sstevel@tonic-gate { 182*0Sstevel@tonic-gate &main'comment("bswapl @_"); 183*0Sstevel@tonic-gate &main'exch(main'HB(@_),main'LB(@_)); 184*0Sstevel@tonic-gate &main'rotr(@_,16); 185*0Sstevel@tonic-gate &main'exch(main'HB(@_),main'LB(@_)); 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate else 188*0Sstevel@tonic-gate { 189*0Sstevel@tonic-gate &out1("bswapl",@_); 190*0Sstevel@tonic-gate } 191*0Sstevel@tonic-gate } 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gatesub out2 194*0Sstevel@tonic-gate { 195*0Sstevel@tonic-gate local($name,$p1,$p2)=@_; 196*0Sstevel@tonic-gate local($l,$ll,$t); 197*0Sstevel@tonic-gate local(%special)=( "roll",0xD1C0,"rorl",0xD1C8, 198*0Sstevel@tonic-gate "rcll",0xD1D0,"rcrl",0xD1D8, 199*0Sstevel@tonic-gate "shll",0xD1E0,"shrl",0xD1E8, 200*0Sstevel@tonic-gate "sarl",0xD1F8); 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1)) 203*0Sstevel@tonic-gate { 204*0Sstevel@tonic-gate $op=$special{$name}|$reg_val{$p1}; 205*0Sstevel@tonic-gate $tmp1=sprintf(".byte %d\n",($op>>8)&0xff); 206*0Sstevel@tonic-gate $tmp2=sprintf(".byte %d\t",$op &0xff); 207*0Sstevel@tonic-gate push(@out,$tmp1); 208*0Sstevel@tonic-gate push(@out,$tmp2); 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate $p2=&conv($p2); 211*0Sstevel@tonic-gate $p1=&conv($p1); 212*0Sstevel@tonic-gate &main'comment("$name $p2 $p1"); 213*0Sstevel@tonic-gate return; 214*0Sstevel@tonic-gate } 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate push(@out,"\t$name\t"); 217*0Sstevel@tonic-gate $t=&conv($p2).","; 218*0Sstevel@tonic-gate $l=length($t); 219*0Sstevel@tonic-gate push(@out,$t); 220*0Sstevel@tonic-gate $ll=4-($l+9)/8; 221*0Sstevel@tonic-gate $tmp1=sprintf("\t" x $ll); 222*0Sstevel@tonic-gate push(@out,$tmp1); 223*0Sstevel@tonic-gate push(@out,&conv($p1)."\n"); 224*0Sstevel@tonic-gate } 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gatesub out1 227*0Sstevel@tonic-gate { 228*0Sstevel@tonic-gate local($name,$p1)=@_; 229*0Sstevel@tonic-gate local($l,$t); 230*0Sstevel@tonic-gate local(%special)=("bswapl",0x0FC8); 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate if ((defined($special{$name})) && defined($regs{$p1})) 233*0Sstevel@tonic-gate { 234*0Sstevel@tonic-gate $op=$special{$name}|$reg_val{$p1}; 235*0Sstevel@tonic-gate $tmp1=sprintf(".byte %d\n",($op>>8)&0xff); 236*0Sstevel@tonic-gate $tmp2=sprintf(".byte %d\t",$op &0xff); 237*0Sstevel@tonic-gate push(@out,$tmp1); 238*0Sstevel@tonic-gate push(@out,$tmp2); 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate $p2=&conv($p2); 241*0Sstevel@tonic-gate $p1=&conv($p1); 242*0Sstevel@tonic-gate &main'comment("$name $p2 $p1"); 243*0Sstevel@tonic-gate return; 244*0Sstevel@tonic-gate } 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate push(@out,"\t$name\t".&conv($p1)."\n"); 247*0Sstevel@tonic-gate } 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gatesub out1p 250*0Sstevel@tonic-gate { 251*0Sstevel@tonic-gate local($name,$p1)=@_; 252*0Sstevel@tonic-gate local($l,$t); 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate push(@out,"\t$name\t*".&conv($p1)."\n"); 255*0Sstevel@tonic-gate } 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gatesub out0 258*0Sstevel@tonic-gate { 259*0Sstevel@tonic-gate push(@out,"\t$_[0]\n"); 260*0Sstevel@tonic-gate } 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gatesub conv 263*0Sstevel@tonic-gate { 264*0Sstevel@tonic-gate local($p)=@_; 265*0Sstevel@tonic-gate 266*0Sstevel@tonic-gate# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate $p=$regs{$p} if (defined($regs{$p})); 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate $p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/; 271*0Sstevel@tonic-gate $p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/; 272*0Sstevel@tonic-gate return $p; 273*0Sstevel@tonic-gate } 274*0Sstevel@tonic-gate 275*0Sstevel@tonic-gatesub main'file 276*0Sstevel@tonic-gate { 277*0Sstevel@tonic-gate local($file)=@_; 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate local($tmp)=<<"EOF"; 280*0Sstevel@tonic-gate .file "$file.s" 281*0Sstevel@tonic-gate .version "01.01" 282*0Sstevel@tonic-gategcc2_compiled.: 283*0Sstevel@tonic-gateEOF 284*0Sstevel@tonic-gate push(@out,$tmp); 285*0Sstevel@tonic-gate } 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gatesub main'function_begin 288*0Sstevel@tonic-gate { 289*0Sstevel@tonic-gate local($func)=@_; 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate &main'external_label($func); 292*0Sstevel@tonic-gate $func=$under.$func; 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate local($tmp)=<<"EOF"; 295*0Sstevel@tonic-gate.text 296*0Sstevel@tonic-gate .align $align 297*0Sstevel@tonic-gate.globl $func 298*0Sstevel@tonic-gateEOF 299*0Sstevel@tonic-gate push(@out,$tmp); 300*0Sstevel@tonic-gate if ($main'cpp) 301*0Sstevel@tonic-gate { $tmp=push(@out,"\tTYPE($func,\@function)\n"); } 302*0Sstevel@tonic-gate elsif ($main'gaswin) 303*0Sstevel@tonic-gate { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } 304*0Sstevel@tonic-gate else { $tmp=push(@out,"\t.type\t$func,\@function\n"); } 305*0Sstevel@tonic-gate push(@out,"$func:\n"); 306*0Sstevel@tonic-gate $tmp=<<"EOF"; 307*0Sstevel@tonic-gate pushl %ebp 308*0Sstevel@tonic-gate pushl %ebx 309*0Sstevel@tonic-gate pushl %esi 310*0Sstevel@tonic-gate pushl %edi 311*0Sstevel@tonic-gate 312*0Sstevel@tonic-gateEOF 313*0Sstevel@tonic-gate push(@out,$tmp); 314*0Sstevel@tonic-gate $stack=20; 315*0Sstevel@tonic-gate } 316*0Sstevel@tonic-gate 317*0Sstevel@tonic-gatesub main'function_begin_B 318*0Sstevel@tonic-gate { 319*0Sstevel@tonic-gate local($func,$extra)=@_; 320*0Sstevel@tonic-gate 321*0Sstevel@tonic-gate &main'external_label($func); 322*0Sstevel@tonic-gate $func=$under.$func; 323*0Sstevel@tonic-gate 324*0Sstevel@tonic-gate local($tmp)=<<"EOF"; 325*0Sstevel@tonic-gate.text 326*0Sstevel@tonic-gate .align $align 327*0Sstevel@tonic-gate.globl $func 328*0Sstevel@tonic-gateEOF 329*0Sstevel@tonic-gate push(@out,$tmp); 330*0Sstevel@tonic-gate if ($main'cpp) 331*0Sstevel@tonic-gate { push(@out,"\tTYPE($func,\@function)\n"); } 332*0Sstevel@tonic-gate elsif ($main'gaswin) 333*0Sstevel@tonic-gate { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } 334*0Sstevel@tonic-gate else { push(@out,"\t.type $func,\@function\n"); } 335*0Sstevel@tonic-gate push(@out,"$func:\n"); 336*0Sstevel@tonic-gate $stack=4; 337*0Sstevel@tonic-gate } 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gatesub main'function_end 340*0Sstevel@tonic-gate { 341*0Sstevel@tonic-gate local($func)=@_; 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gate $func=$under.$func; 344*0Sstevel@tonic-gate 345*0Sstevel@tonic-gate local($tmp)=<<"EOF"; 346*0Sstevel@tonic-gate popl %edi 347*0Sstevel@tonic-gate popl %esi 348*0Sstevel@tonic-gate popl %ebx 349*0Sstevel@tonic-gate popl %ebp 350*0Sstevel@tonic-gate ret 351*0Sstevel@tonic-gate.L_${func}_end: 352*0Sstevel@tonic-gateEOF 353*0Sstevel@tonic-gate push(@out,$tmp); 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate if ($main'cpp) 356*0Sstevel@tonic-gate { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); } 357*0Sstevel@tonic-gate elsif ($main'gaswin) 358*0Sstevel@tonic-gate { $tmp=push(@out,"\t.align 4\n"); } 359*0Sstevel@tonic-gate else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); } 360*0Sstevel@tonic-gate push(@out,".ident \"$func\"\n"); 361*0Sstevel@tonic-gate $stack=0; 362*0Sstevel@tonic-gate %label=(); 363*0Sstevel@tonic-gate } 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gatesub main'function_end_A 366*0Sstevel@tonic-gate { 367*0Sstevel@tonic-gate local($func)=@_; 368*0Sstevel@tonic-gate 369*0Sstevel@tonic-gate local($tmp)=<<"EOF"; 370*0Sstevel@tonic-gate popl %edi 371*0Sstevel@tonic-gate popl %esi 372*0Sstevel@tonic-gate popl %ebx 373*0Sstevel@tonic-gate popl %ebp 374*0Sstevel@tonic-gate ret 375*0Sstevel@tonic-gateEOF 376*0Sstevel@tonic-gate push(@out,$tmp); 377*0Sstevel@tonic-gate } 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gatesub main'function_end_B 380*0Sstevel@tonic-gate { 381*0Sstevel@tonic-gate local($func)=@_; 382*0Sstevel@tonic-gate 383*0Sstevel@tonic-gate $func=$under.$func; 384*0Sstevel@tonic-gate 385*0Sstevel@tonic-gate push(@out,".L_${func}_end:\n"); 386*0Sstevel@tonic-gate if ($main'cpp) 387*0Sstevel@tonic-gate { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); } 388*0Sstevel@tonic-gate elsif ($main'gaswin) 389*0Sstevel@tonic-gate { push(@out,"\t.align 4\n"); } 390*0Sstevel@tonic-gate else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); } 391*0Sstevel@tonic-gate push(@out,".ident \"desasm.pl\"\n"); 392*0Sstevel@tonic-gate $stack=0; 393*0Sstevel@tonic-gate %label=(); 394*0Sstevel@tonic-gate } 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gatesub main'wparam 397*0Sstevel@tonic-gate { 398*0Sstevel@tonic-gate local($num)=@_; 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate return(&main'DWP($stack+$num*4,"esp","",0)); 401*0Sstevel@tonic-gate } 402*0Sstevel@tonic-gate 403*0Sstevel@tonic-gatesub main'stack_push 404*0Sstevel@tonic-gate { 405*0Sstevel@tonic-gate local($num)=@_; 406*0Sstevel@tonic-gate $stack+=$num*4; 407*0Sstevel@tonic-gate &main'sub("esp",$num*4); 408*0Sstevel@tonic-gate } 409*0Sstevel@tonic-gate 410*0Sstevel@tonic-gatesub main'stack_pop 411*0Sstevel@tonic-gate { 412*0Sstevel@tonic-gate local($num)=@_; 413*0Sstevel@tonic-gate $stack-=$num*4; 414*0Sstevel@tonic-gate &main'add("esp",$num*4); 415*0Sstevel@tonic-gate } 416*0Sstevel@tonic-gate 417*0Sstevel@tonic-gatesub main'swtmp 418*0Sstevel@tonic-gate { 419*0Sstevel@tonic-gate return(&main'DWP($_[0]*4,"esp","",0)); 420*0Sstevel@tonic-gate } 421*0Sstevel@tonic-gate 422*0Sstevel@tonic-gate# Should use swtmp, which is above esp. Linix can trash the stack above esp 423*0Sstevel@tonic-gate#sub main'wtmp 424*0Sstevel@tonic-gate# { 425*0Sstevel@tonic-gate# local($num)=@_; 426*0Sstevel@tonic-gate# 427*0Sstevel@tonic-gate# return(&main'DWP(-($num+1)*4,"esp","",0)); 428*0Sstevel@tonic-gate# } 429*0Sstevel@tonic-gate 430*0Sstevel@tonic-gatesub main'comment 431*0Sstevel@tonic-gate { 432*0Sstevel@tonic-gate if ($main'elf) # GNU and SVR4 as'es use different comment delimiters, 433*0Sstevel@tonic-gate { # so we just skip comments... 434*0Sstevel@tonic-gate push(@out,"\n"); 435*0Sstevel@tonic-gate return; 436*0Sstevel@tonic-gate } 437*0Sstevel@tonic-gate foreach (@_) 438*0Sstevel@tonic-gate { 439*0Sstevel@tonic-gate if (/^\s*$/) 440*0Sstevel@tonic-gate { push(@out,"\n"); } 441*0Sstevel@tonic-gate else 442*0Sstevel@tonic-gate { push(@out,"\t$com_start $_ $com_end\n"); } 443*0Sstevel@tonic-gate } 444*0Sstevel@tonic-gate } 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gatesub main'label 447*0Sstevel@tonic-gate { 448*0Sstevel@tonic-gate if (!defined($label{$_[0]})) 449*0Sstevel@tonic-gate { 450*0Sstevel@tonic-gate $label{$_[0]}=".${label}${_[0]}"; 451*0Sstevel@tonic-gate $label++; 452*0Sstevel@tonic-gate } 453*0Sstevel@tonic-gate return($label{$_[0]}); 454*0Sstevel@tonic-gate } 455*0Sstevel@tonic-gate 456*0Sstevel@tonic-gatesub main'set_label 457*0Sstevel@tonic-gate { 458*0Sstevel@tonic-gate if (!defined($label{$_[0]})) 459*0Sstevel@tonic-gate { 460*0Sstevel@tonic-gate $label{$_[0]}=".${label}${_[0]}"; 461*0Sstevel@tonic-gate $label++; 462*0Sstevel@tonic-gate } 463*0Sstevel@tonic-gate push(@out,".align $align\n") if ($_[1] != 0); 464*0Sstevel@tonic-gate push(@out,"$label{$_[0]}:\n"); 465*0Sstevel@tonic-gate } 466*0Sstevel@tonic-gate 467*0Sstevel@tonic-gatesub main'file_end 468*0Sstevel@tonic-gate { 469*0Sstevel@tonic-gate if ($const ne "") 470*0Sstevel@tonic-gate { 471*0Sstevel@tonic-gate push(@out,".section .rodata\n"); 472*0Sstevel@tonic-gate push(@out,$const); 473*0Sstevel@tonic-gate $const=""; 474*0Sstevel@tonic-gate } 475*0Sstevel@tonic-gate } 476*0Sstevel@tonic-gate 477*0Sstevel@tonic-gatesub main'data_word 478*0Sstevel@tonic-gate { 479*0Sstevel@tonic-gate push(@out,"\t.long $_[0]\n"); 480*0Sstevel@tonic-gate } 481*0Sstevel@tonic-gate 482*0Sstevel@tonic-gate# debug output functions: puts, putx, printf 483*0Sstevel@tonic-gate 484*0Sstevel@tonic-gatesub main'puts 485*0Sstevel@tonic-gate { 486*0Sstevel@tonic-gate &pushvars(); 487*0Sstevel@tonic-gate &main'push('$Lstring' . ++$constl); 488*0Sstevel@tonic-gate &main'call('puts'); 489*0Sstevel@tonic-gate $stack-=4; 490*0Sstevel@tonic-gate &main'add("esp",4); 491*0Sstevel@tonic-gate &popvars(); 492*0Sstevel@tonic-gate 493*0Sstevel@tonic-gate $const .= "Lstring$constl:\n\t.string \"@_[0]\"\n"; 494*0Sstevel@tonic-gate } 495*0Sstevel@tonic-gate 496*0Sstevel@tonic-gatesub main'putx 497*0Sstevel@tonic-gate { 498*0Sstevel@tonic-gate &pushvars(); 499*0Sstevel@tonic-gate &main'push($_[0]); 500*0Sstevel@tonic-gate &main'push('$Lstring' . ++$constl); 501*0Sstevel@tonic-gate &main'call('printf'); 502*0Sstevel@tonic-gate &main'add("esp",8); 503*0Sstevel@tonic-gate $stack-=8; 504*0Sstevel@tonic-gate &popvars(); 505*0Sstevel@tonic-gate 506*0Sstevel@tonic-gate $const .= "Lstring$constl:\n\t.string \"\%X\"\n"; 507*0Sstevel@tonic-gate } 508*0Sstevel@tonic-gate 509*0Sstevel@tonic-gatesub main'printf 510*0Sstevel@tonic-gate { 511*0Sstevel@tonic-gate $ostack = $stack; 512*0Sstevel@tonic-gate &pushvars(); 513*0Sstevel@tonic-gate for ($i = @_ - 1; $i >= 0; $i--) 514*0Sstevel@tonic-gate { 515*0Sstevel@tonic-gate if ($i == 0) # change this to support %s format strings 516*0Sstevel@tonic-gate { 517*0Sstevel@tonic-gate &main'push('$Lstring' . ++$constl); 518*0Sstevel@tonic-gate $const .= "Lstring$constl:\n\t.string \"@_[$i]\"\n"; 519*0Sstevel@tonic-gate } 520*0Sstevel@tonic-gate else 521*0Sstevel@tonic-gate { 522*0Sstevel@tonic-gate if ($_[$i] =~ /([0-9]*)\(%esp\)/) 523*0Sstevel@tonic-gate { 524*0Sstevel@tonic-gate &main'push(($1 + $stack - $ostack) . '(%esp)'); 525*0Sstevel@tonic-gate } 526*0Sstevel@tonic-gate else 527*0Sstevel@tonic-gate { 528*0Sstevel@tonic-gate &main'push($_[$i]); 529*0Sstevel@tonic-gate } 530*0Sstevel@tonic-gate } 531*0Sstevel@tonic-gate } 532*0Sstevel@tonic-gate &main'call('printf'); 533*0Sstevel@tonic-gate $stack-=4*@_; 534*0Sstevel@tonic-gate &main'add("esp",4*@_); 535*0Sstevel@tonic-gate &popvars(); 536*0Sstevel@tonic-gate } 537*0Sstevel@tonic-gate 538*0Sstevel@tonic-gatesub pushvars 539*0Sstevel@tonic-gate { 540*0Sstevel@tonic-gate &main'pushf(); 541*0Sstevel@tonic-gate &main'push("edx"); 542*0Sstevel@tonic-gate &main'push("ecx"); 543*0Sstevel@tonic-gate &main'push("eax"); 544*0Sstevel@tonic-gate } 545*0Sstevel@tonic-gate 546*0Sstevel@tonic-gatesub popvars 547*0Sstevel@tonic-gate { 548*0Sstevel@tonic-gate &main'pop("eax"); 549*0Sstevel@tonic-gate &main'pop("ecx"); 550*0Sstevel@tonic-gate &main'pop("edx"); 551*0Sstevel@tonic-gate &main'popf(); 552*0Sstevel@tonic-gate } 553*0Sstevel@tonic-gate 554*0Sstevel@tonic-gatesub main'picmeup 555*0Sstevel@tonic-gate { 556*0Sstevel@tonic-gate local($dst,$sym)=@_; 557*0Sstevel@tonic-gate if ($main'cpp) 558*0Sstevel@tonic-gate { 559*0Sstevel@tonic-gate local($tmp)=<<___; 560*0Sstevel@tonic-gate#if (defined(ELF) || defined(SOL)) && defined(PIC) 561*0Sstevel@tonic-gate .align 8 562*0Sstevel@tonic-gate call 1f 563*0Sstevel@tonic-gate1: popl $regs{$dst} 564*0Sstevel@tonic-gate addl \$_GLOBAL_OFFSET_TABLE_+[.-1b],$regs{$dst} 565*0Sstevel@tonic-gate movl $sym\@GOT($regs{$dst}),$regs{$dst} 566*0Sstevel@tonic-gate#else 567*0Sstevel@tonic-gate leal $sym,$regs{$dst} 568*0Sstevel@tonic-gate#endif 569*0Sstevel@tonic-gate___ 570*0Sstevel@tonic-gate push(@out,$tmp); 571*0Sstevel@tonic-gate } 572*0Sstevel@tonic-gate elsif ($main'pic && ($main'elf || $main'aout)) 573*0Sstevel@tonic-gate { 574*0Sstevel@tonic-gate push(@out,"\t.align\t8\n"); 575*0Sstevel@tonic-gate &main'call(&main'label("PIC_me_up")); 576*0Sstevel@tonic-gate &main'set_label("PIC_me_up"); 577*0Sstevel@tonic-gate &main'blindpop($dst); 578*0Sstevel@tonic-gate &main'add($dst,"\$$under"."_GLOBAL_OFFSET_TABLE_+[.-". 579*0Sstevel@tonic-gate &main'label("PIC_me_up") . "]"); 580*0Sstevel@tonic-gate &main'mov($dst,&main'DWP($sym."\@GOT",$dst)); 581*0Sstevel@tonic-gate } 582*0Sstevel@tonic-gate else 583*0Sstevel@tonic-gate { 584*0Sstevel@tonic-gate &main'lea($dst,&main'DWP($sym)); 585*0Sstevel@tonic-gate } 586*0Sstevel@tonic-gate } 587*0Sstevel@tonic-gate 588*0Sstevel@tonic-gatesub main'blindpop { &out1("popl",@_); } 589