39 sub main::asm_init_output { @out=(); }
40 sub main::asm_get_output { return(@out); }
41 sub main::get_labels { return(@labels); }
43 sub main::external_label
47 push(@out, "extern\t_$_\n");
53 (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
59 (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
87 &main::sub("esp",$num*4);
94 &main::add("esp",$num*4);
99 my($size,$addr,$reg1,$reg2,$idx)=@_;
103 if ($addr =~ /^(.+)\+(.+)$/)
105 if (defined($regs{$reg2})) {
106 $addr=join('+', &conv($1), "_$2");
112 elsif ($addr =~ /^[_a-zA-Z]/)
117 $reg1="$regs{$reg1}" if defined($regs{$reg1});
118 $reg2="$regs{$reg2}" if defined($regs{$reg2});
119 if (($addr ne "") && ($addr ne 0))
122 { $ret.="${addr}+"; }
123 else { $post=$addr; }
128 $t="*$idx" if ($idx != 0);
129 $reg1="+".$reg1 if ("$reg1$post" ne "");
130 $ret.="$reg2$t$reg1$post]";
139 sub main::mov { &out2("mov",@_); }
140 sub main::movb { &out2("mov",@_); }
141 sub main::and { &out2("and",@_); }
142 sub main::or { &out2("or",@_); }
143 sub main::shl { &out2("shl",@_); }
144 sub main::shr { &out2("shr",@_); }
145 sub main::xor { &out2("xor",@_); }
146 sub main::xorb { &out2("xor",@_); }
147 sub main::add { &out2("add",@_); }
148 sub main::adc { &out2("adc",@_); }
149 sub main::sub { &out2("sub",@_); }
150 sub main::rotl { &out2("rol",@_); }
151 sub main::rotr { &out2("ror",@_); }
152 sub main::exch { &out2("xchg",@_); }
153 sub main::cmp { &out2("cmp",@_); }
154 sub main::lea { &out2("lea",@_); }
155 sub main::mul { &out1("mul",@_); }
156 sub main::div { &out1("div",@_); }
157 sub main::dec { &out1("dec",@_); }
158 sub main::inc { &out1("inc",@_); }
159 sub main::jmp { &out1("jmp",@_); }
160 sub main::jmp_ptr { &out1p("jmp",@_); }
162 # This is a bit of a kludge: declare all branches as NEAR.
163 sub main::je { &out1("je NEAR",@_); }
164 sub main::jle { &out1("jle NEAR",@_); }
165 sub main::jz { &out1("jz NEAR",@_); }
166 sub main::jge { &out1("jge NEAR",@_); }
167 sub main::jl { &out1("jl NEAR",@_); }
168 sub main::jb { &out1("jb NEAR",@_); }
169 sub main::jc { &out1("jc NEAR",@_); }
170 sub main::jnc { &out1("jnc NEAR",@_); }
171 sub main::jnz { &out1("jnz NEAR",@_); }
172 sub main::jne { &out1("jne NEAR",@_); }
173 sub main::jno { &out1("jno NEAR",@_); }
175 sub main::push { &out1("push",@_); $stack+=4; }
176 sub main::pop { &out1("pop",@_); $stack-=4; }
177 sub main::bswap { &out1("bswap",@_); &using486(); }
178 sub main::not { &out1("not",@_); }
179 sub main::call { &out1("call",'_'.$_[0]); }
180 sub main::ret { &out0("ret"); }
181 sub main::nop { &out0("nop"); }
185 my($name,$p1,$p2)=@_;
188 push(@out,"\t$name\t");
193 push(@out,"\t" x $l);
194 push(@out,&conv($p2));
202 push(@out,"\t$name\n");
209 push(@out,"\t$name\t".&conv($p1)."\n");
215 $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
223 grep(s/\.386/\.486/,@out);
228 push(@out, "segment .text\n");
231 sub main::function_begin
248 sub main::function_begin_B
259 sub main::function_end
275 sub main::function_end_B
281 sub main::function_end_A
303 return(&main::DWP($stack+$num*4,"esp","",0));
308 return(&main::DWP($_[0]*4,"esp","",0));
311 # Should use swtmp, which is above esp. Linix can trash the stack above esp
316 # return(&main::DWP(-(($num+1)*4),"esp","",0));
323 push(@out,"\t; $_\n");
329 if (!defined($label{$_[0]}))
331 $label{$_[0]}="\$${label}${_[0]}";
334 return($label{$_[0]});
339 if (!defined($label{$_[0]}))
341 $label{$_[0]}="${label}${_[0]}";
344 push(@out,"$label{$_[0]}:\n");
349 push(@out,"\tDD\t$_[0]\n");
357 push(@out,"\t$name\t ".&conv($p1)."\n");
361 ## Additional functions required for MMX and other ops
363 sub main::testb { &out2('test', @_) }
364 sub main::movzx { &out2('movzx', @_) }
365 sub main::movd { &out2('movd', @_) }
366 sub main::emms { &out0('emms', @_) }