xref: /onnv-gate/usr/src/common/openssl/crypto/perlasm/x86ms.pl (revision 0:68f95e015346)
1*0Sstevel@tonic-gate#!/usr/local/bin/perl
2*0Sstevel@tonic-gate
3*0Sstevel@tonic-gatepackage x86ms;
4*0Sstevel@tonic-gate
5*0Sstevel@tonic-gate$label="L000";
6*0Sstevel@tonic-gate
7*0Sstevel@tonic-gate%lb=(	'eax',	'al',
8*0Sstevel@tonic-gate	'ebx',	'bl',
9*0Sstevel@tonic-gate	'ecx',	'cl',
10*0Sstevel@tonic-gate	'edx',	'dl',
11*0Sstevel@tonic-gate	'ax',	'al',
12*0Sstevel@tonic-gate	'bx',	'bl',
13*0Sstevel@tonic-gate	'cx',	'cl',
14*0Sstevel@tonic-gate	'dx',	'dl',
15*0Sstevel@tonic-gate	);
16*0Sstevel@tonic-gate
17*0Sstevel@tonic-gate%hb=(	'eax',	'ah',
18*0Sstevel@tonic-gate	'ebx',	'bh',
19*0Sstevel@tonic-gate	'ecx',	'ch',
20*0Sstevel@tonic-gate	'edx',	'dh',
21*0Sstevel@tonic-gate	'ax',	'ah',
22*0Sstevel@tonic-gate	'bx',	'bh',
23*0Sstevel@tonic-gate	'cx',	'ch',
24*0Sstevel@tonic-gate	'dx',	'dh',
25*0Sstevel@tonic-gate	);
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gatesub main'asm_init_output { @out=(); }
28*0Sstevel@tonic-gatesub main'asm_get_output { return(@out); }
29*0Sstevel@tonic-gatesub main'get_labels { return(@labels); }
30*0Sstevel@tonic-gatesub main'external_label { push(@labels,@_); }
31*0Sstevel@tonic-gate
32*0Sstevel@tonic-gatesub main'LB
33*0Sstevel@tonic-gate	{
34*0Sstevel@tonic-gate	(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
35*0Sstevel@tonic-gate	return($lb{$_[0]});
36*0Sstevel@tonic-gate	}
37*0Sstevel@tonic-gate
38*0Sstevel@tonic-gatesub main'HB
39*0Sstevel@tonic-gate	{
40*0Sstevel@tonic-gate	(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
41*0Sstevel@tonic-gate	return($hb{$_[0]});
42*0Sstevel@tonic-gate	}
43*0Sstevel@tonic-gate
44*0Sstevel@tonic-gatesub main'BP
45*0Sstevel@tonic-gate	{
46*0Sstevel@tonic-gate	&get_mem("BYTE",@_);
47*0Sstevel@tonic-gate	}
48*0Sstevel@tonic-gate
49*0Sstevel@tonic-gatesub main'DWP
50*0Sstevel@tonic-gate	{
51*0Sstevel@tonic-gate	&get_mem("DWORD",@_);
52*0Sstevel@tonic-gate	}
53*0Sstevel@tonic-gate
54*0Sstevel@tonic-gatesub main'BC
55*0Sstevel@tonic-gate	{
56*0Sstevel@tonic-gate	return @_;
57*0Sstevel@tonic-gate	}
58*0Sstevel@tonic-gate
59*0Sstevel@tonic-gatesub main'DWC
60*0Sstevel@tonic-gate	{
61*0Sstevel@tonic-gate	return @_;
62*0Sstevel@tonic-gate	}
63*0Sstevel@tonic-gate
64*0Sstevel@tonic-gatesub main'stack_push
65*0Sstevel@tonic-gate	{
66*0Sstevel@tonic-gate	local($num)=@_;
67*0Sstevel@tonic-gate	$stack+=$num*4;
68*0Sstevel@tonic-gate	&main'sub("esp",$num*4);
69*0Sstevel@tonic-gate	}
70*0Sstevel@tonic-gate
71*0Sstevel@tonic-gatesub main'stack_pop
72*0Sstevel@tonic-gate	{
73*0Sstevel@tonic-gate	local($num)=@_;
74*0Sstevel@tonic-gate	$stack-=$num*4;
75*0Sstevel@tonic-gate	&main'add("esp",$num*4);
76*0Sstevel@tonic-gate	}
77*0Sstevel@tonic-gate
78*0Sstevel@tonic-gatesub get_mem
79*0Sstevel@tonic-gate	{
80*0Sstevel@tonic-gate	local($size,$addr,$reg1,$reg2,$idx)=@_;
81*0Sstevel@tonic-gate	local($t,$post);
82*0Sstevel@tonic-gate	local($ret)="$size PTR ";
83*0Sstevel@tonic-gate
84*0Sstevel@tonic-gate	$addr =~ s/^\s+//;
85*0Sstevel@tonic-gate	if ($addr =~ /^(.+)\+(.+)$/)
86*0Sstevel@tonic-gate		{
87*0Sstevel@tonic-gate		$reg2=&conv($1);
88*0Sstevel@tonic-gate		$addr="_$2";
89*0Sstevel@tonic-gate		}
90*0Sstevel@tonic-gate	elsif ($addr =~ /^[_a-zA-Z]/)
91*0Sstevel@tonic-gate		{
92*0Sstevel@tonic-gate		$addr="_$addr";
93*0Sstevel@tonic-gate		}
94*0Sstevel@tonic-gate
95*0Sstevel@tonic-gate	if ($addr =~ /^.+\-.+$/) { $addr="($addr)"; }
96*0Sstevel@tonic-gate
97*0Sstevel@tonic-gate	$reg1="$regs{$reg1}" if defined($regs{$reg1});
98*0Sstevel@tonic-gate	$reg2="$regs{$reg2}" if defined($regs{$reg2});
99*0Sstevel@tonic-gate	if (($addr ne "") && ($addr ne 0))
100*0Sstevel@tonic-gate		{
101*0Sstevel@tonic-gate		if ($addr !~ /^-/)
102*0Sstevel@tonic-gate			{ $ret.=$addr; }
103*0Sstevel@tonic-gate		else	{ $post=$addr; }
104*0Sstevel@tonic-gate		}
105*0Sstevel@tonic-gate	if ($reg2 ne "")
106*0Sstevel@tonic-gate		{
107*0Sstevel@tonic-gate		$t="";
108*0Sstevel@tonic-gate		$t="*$idx" if ($idx != 0);
109*0Sstevel@tonic-gate		$reg1="+".$reg1 if ("$reg1$post" ne "");
110*0Sstevel@tonic-gate		$ret.="[$reg2$t$reg1$post]";
111*0Sstevel@tonic-gate		}
112*0Sstevel@tonic-gate	else
113*0Sstevel@tonic-gate		{
114*0Sstevel@tonic-gate		$ret.="[$reg1$post]"
115*0Sstevel@tonic-gate		}
116*0Sstevel@tonic-gate	$ret =~ s/\[\]//;	# in case $addr was the only argument
117*0Sstevel@tonic-gate	return($ret);
118*0Sstevel@tonic-gate	}
119*0Sstevel@tonic-gate
120*0Sstevel@tonic-gatesub main'mov	{ &out2("mov",@_); }
121*0Sstevel@tonic-gatesub main'movb	{ &out2("mov",@_); }
122*0Sstevel@tonic-gatesub main'and	{ &out2("and",@_); }
123*0Sstevel@tonic-gatesub main'or	{ &out2("or",@_); }
124*0Sstevel@tonic-gatesub main'shl	{ &out2("shl",@_); }
125*0Sstevel@tonic-gatesub main'shr	{ &out2("shr",@_); }
126*0Sstevel@tonic-gatesub main'xor	{ &out2("xor",@_); }
127*0Sstevel@tonic-gatesub main'xorb	{ &out2("xor",@_); }
128*0Sstevel@tonic-gatesub main'add	{ &out2("add",@_); }
129*0Sstevel@tonic-gatesub main'adc	{ &out2("adc",@_); }
130*0Sstevel@tonic-gatesub main'sub	{ &out2("sub",@_); }
131*0Sstevel@tonic-gatesub main'rotl	{ &out2("rol",@_); }
132*0Sstevel@tonic-gatesub main'rotr	{ &out2("ror",@_); }
133*0Sstevel@tonic-gatesub main'exch	{ &out2("xchg",@_); }
134*0Sstevel@tonic-gatesub main'cmp	{ &out2("cmp",@_); }
135*0Sstevel@tonic-gatesub main'lea	{ &out2("lea",@_); }
136*0Sstevel@tonic-gatesub main'mul	{ &out1("mul",@_); }
137*0Sstevel@tonic-gatesub main'div	{ &out1("div",@_); }
138*0Sstevel@tonic-gatesub main'dec	{ &out1("dec",@_); }
139*0Sstevel@tonic-gatesub main'inc	{ &out1("inc",@_); }
140*0Sstevel@tonic-gatesub main'jmp	{ &out1("jmp",@_); }
141*0Sstevel@tonic-gatesub main'jmp_ptr { &out1p("jmp",@_); }
142*0Sstevel@tonic-gatesub main'je	{ &out1("je",@_); }
143*0Sstevel@tonic-gatesub main'jle	{ &out1("jle",@_); }
144*0Sstevel@tonic-gatesub main'jz	{ &out1("jz",@_); }
145*0Sstevel@tonic-gatesub main'jge	{ &out1("jge",@_); }
146*0Sstevel@tonic-gatesub main'jl	{ &out1("jl",@_); }
147*0Sstevel@tonic-gatesub main'ja	{ &out1("ja",@_); }
148*0Sstevel@tonic-gatesub main'jae	{ &out1("jae",@_); }
149*0Sstevel@tonic-gatesub main'jb	{ &out1("jb",@_); }
150*0Sstevel@tonic-gatesub main'jbe	{ &out1("jbe",@_); }
151*0Sstevel@tonic-gatesub main'jc	{ &out1("jc",@_); }
152*0Sstevel@tonic-gatesub main'jnc	{ &out1("jnc",@_); }
153*0Sstevel@tonic-gatesub main'jnz	{ &out1("jnz",@_); }
154*0Sstevel@tonic-gatesub main'jne	{ &out1("jne",@_); }
155*0Sstevel@tonic-gatesub main'jno	{ &out1("jno",@_); }
156*0Sstevel@tonic-gatesub main'push	{ &out1("push",@_); $stack+=4; }
157*0Sstevel@tonic-gatesub main'pop	{ &out1("pop",@_); $stack-=4; }
158*0Sstevel@tonic-gatesub main'bswap	{ &out1("bswap",@_); &using486(); }
159*0Sstevel@tonic-gatesub main'not	{ &out1("not",@_); }
160*0Sstevel@tonic-gatesub main'call	{ &out1("call",($_[0]=~/^\$L/?'':'_').$_[0]); }
161*0Sstevel@tonic-gatesub main'ret	{ &out0("ret"); }
162*0Sstevel@tonic-gatesub main'nop	{ &out0("nop"); }
163*0Sstevel@tonic-gate
164*0Sstevel@tonic-gatesub out2
165*0Sstevel@tonic-gate	{
166*0Sstevel@tonic-gate	local($name,$p1,$p2)=@_;
167*0Sstevel@tonic-gate	local($l,$t);
168*0Sstevel@tonic-gate
169*0Sstevel@tonic-gate	push(@out,"\t$name\t");
170*0Sstevel@tonic-gate	$t=&conv($p1).",";
171*0Sstevel@tonic-gate	$l=length($t);
172*0Sstevel@tonic-gate	push(@out,$t);
173*0Sstevel@tonic-gate	$l=4-($l+9)/8;
174*0Sstevel@tonic-gate	push(@out,"\t" x $l);
175*0Sstevel@tonic-gate	push(@out,&conv($p2));
176*0Sstevel@tonic-gate	push(@out,"\n");
177*0Sstevel@tonic-gate	}
178*0Sstevel@tonic-gate
179*0Sstevel@tonic-gatesub out0
180*0Sstevel@tonic-gate	{
181*0Sstevel@tonic-gate	local($name)=@_;
182*0Sstevel@tonic-gate
183*0Sstevel@tonic-gate	push(@out,"\t$name\n");
184*0Sstevel@tonic-gate	}
185*0Sstevel@tonic-gate
186*0Sstevel@tonic-gatesub out1
187*0Sstevel@tonic-gate	{
188*0Sstevel@tonic-gate	local($name,$p1)=@_;
189*0Sstevel@tonic-gate	local($l,$t);
190*0Sstevel@tonic-gate
191*0Sstevel@tonic-gate	push(@out,"\t$name\t".&conv($p1)."\n");
192*0Sstevel@tonic-gate	}
193*0Sstevel@tonic-gate
194*0Sstevel@tonic-gatesub conv
195*0Sstevel@tonic-gate	{
196*0Sstevel@tonic-gate	local($p)=@_;
197*0Sstevel@tonic-gate
198*0Sstevel@tonic-gate	$p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
199*0Sstevel@tonic-gate	return $p;
200*0Sstevel@tonic-gate	}
201*0Sstevel@tonic-gate
202*0Sstevel@tonic-gatesub using486
203*0Sstevel@tonic-gate	{
204*0Sstevel@tonic-gate	return if $using486;
205*0Sstevel@tonic-gate	$using486++;
206*0Sstevel@tonic-gate	grep(s/\.386/\.486/,@out);
207*0Sstevel@tonic-gate	}
208*0Sstevel@tonic-gate
209*0Sstevel@tonic-gatesub main'file
210*0Sstevel@tonic-gate	{
211*0Sstevel@tonic-gate	local($file)=@_;
212*0Sstevel@tonic-gate
213*0Sstevel@tonic-gate	local($tmp)=<<"EOF";
214*0Sstevel@tonic-gate	TITLE	$file.asm
215*0Sstevel@tonic-gate        .386
216*0Sstevel@tonic-gate.model FLAT
217*0Sstevel@tonic-gateEOF
218*0Sstevel@tonic-gate	push(@out,$tmp);
219*0Sstevel@tonic-gate	}
220*0Sstevel@tonic-gate
221*0Sstevel@tonic-gatesub main'function_begin
222*0Sstevel@tonic-gate	{
223*0Sstevel@tonic-gate	local($func,$extra)=@_;
224*0Sstevel@tonic-gate
225*0Sstevel@tonic-gate	push(@labels,$func);
226*0Sstevel@tonic-gate
227*0Sstevel@tonic-gate	local($tmp)=<<"EOF";
228*0Sstevel@tonic-gate_TEXT	SEGMENT
229*0Sstevel@tonic-gatePUBLIC	_$func
230*0Sstevel@tonic-gate$extra
231*0Sstevel@tonic-gate_$func PROC NEAR
232*0Sstevel@tonic-gate	push	ebp
233*0Sstevel@tonic-gate	push	ebx
234*0Sstevel@tonic-gate	push	esi
235*0Sstevel@tonic-gate	push	edi
236*0Sstevel@tonic-gateEOF
237*0Sstevel@tonic-gate	push(@out,$tmp);
238*0Sstevel@tonic-gate	$stack=20;
239*0Sstevel@tonic-gate	}
240*0Sstevel@tonic-gate
241*0Sstevel@tonic-gatesub main'function_begin_B
242*0Sstevel@tonic-gate	{
243*0Sstevel@tonic-gate	local($func,$extra)=@_;
244*0Sstevel@tonic-gate
245*0Sstevel@tonic-gate	local($tmp)=<<"EOF";
246*0Sstevel@tonic-gate_TEXT	SEGMENT
247*0Sstevel@tonic-gatePUBLIC	_$func
248*0Sstevel@tonic-gate$extra
249*0Sstevel@tonic-gate_$func PROC NEAR
250*0Sstevel@tonic-gateEOF
251*0Sstevel@tonic-gate	push(@out,$tmp);
252*0Sstevel@tonic-gate	$stack=4;
253*0Sstevel@tonic-gate	}
254*0Sstevel@tonic-gate
255*0Sstevel@tonic-gatesub main'function_end
256*0Sstevel@tonic-gate	{
257*0Sstevel@tonic-gate	local($func)=@_;
258*0Sstevel@tonic-gate
259*0Sstevel@tonic-gate	local($tmp)=<<"EOF";
260*0Sstevel@tonic-gate	pop	edi
261*0Sstevel@tonic-gate	pop	esi
262*0Sstevel@tonic-gate	pop	ebx
263*0Sstevel@tonic-gate	pop	ebp
264*0Sstevel@tonic-gate	ret
265*0Sstevel@tonic-gate_$func ENDP
266*0Sstevel@tonic-gate_TEXT	ENDS
267*0Sstevel@tonic-gateEOF
268*0Sstevel@tonic-gate	push(@out,$tmp);
269*0Sstevel@tonic-gate	$stack=0;
270*0Sstevel@tonic-gate	%label=();
271*0Sstevel@tonic-gate	}
272*0Sstevel@tonic-gate
273*0Sstevel@tonic-gatesub main'function_end_B
274*0Sstevel@tonic-gate	{
275*0Sstevel@tonic-gate	local($func)=@_;
276*0Sstevel@tonic-gate
277*0Sstevel@tonic-gate	local($tmp)=<<"EOF";
278*0Sstevel@tonic-gate_$func ENDP
279*0Sstevel@tonic-gate_TEXT	ENDS
280*0Sstevel@tonic-gateEOF
281*0Sstevel@tonic-gate	push(@out,$tmp);
282*0Sstevel@tonic-gate	$stack=0;
283*0Sstevel@tonic-gate	%label=();
284*0Sstevel@tonic-gate	}
285*0Sstevel@tonic-gate
286*0Sstevel@tonic-gatesub main'function_end_A
287*0Sstevel@tonic-gate	{
288*0Sstevel@tonic-gate	local($func)=@_;
289*0Sstevel@tonic-gate
290*0Sstevel@tonic-gate	local($tmp)=<<"EOF";
291*0Sstevel@tonic-gate	pop	edi
292*0Sstevel@tonic-gate	pop	esi
293*0Sstevel@tonic-gate	pop	ebx
294*0Sstevel@tonic-gate	pop	ebp
295*0Sstevel@tonic-gate	ret
296*0Sstevel@tonic-gateEOF
297*0Sstevel@tonic-gate	push(@out,$tmp);
298*0Sstevel@tonic-gate	}
299*0Sstevel@tonic-gate
300*0Sstevel@tonic-gatesub main'file_end
301*0Sstevel@tonic-gate	{
302*0Sstevel@tonic-gate	push(@out,"END\n");
303*0Sstevel@tonic-gate	}
304*0Sstevel@tonic-gate
305*0Sstevel@tonic-gatesub main'wparam
306*0Sstevel@tonic-gate	{
307*0Sstevel@tonic-gate	local($num)=@_;
308*0Sstevel@tonic-gate
309*0Sstevel@tonic-gate	return(&main'DWP($stack+$num*4,"esp","",0));
310*0Sstevel@tonic-gate	}
311*0Sstevel@tonic-gate
312*0Sstevel@tonic-gatesub main'swtmp
313*0Sstevel@tonic-gate	{
314*0Sstevel@tonic-gate	return(&main'DWP($_[0]*4,"esp","",0));
315*0Sstevel@tonic-gate	}
316*0Sstevel@tonic-gate
317*0Sstevel@tonic-gate# Should use swtmp, which is above esp.  Linix can trash the stack above esp
318*0Sstevel@tonic-gate#sub main'wtmp
319*0Sstevel@tonic-gate#	{
320*0Sstevel@tonic-gate#	local($num)=@_;
321*0Sstevel@tonic-gate#
322*0Sstevel@tonic-gate#	return(&main'DWP(-(($num+1)*4),"esp","",0));
323*0Sstevel@tonic-gate#	}
324*0Sstevel@tonic-gate
325*0Sstevel@tonic-gatesub main'comment
326*0Sstevel@tonic-gate	{
327*0Sstevel@tonic-gate	foreach (@_)
328*0Sstevel@tonic-gate		{
329*0Sstevel@tonic-gate		push(@out,"\t; $_\n");
330*0Sstevel@tonic-gate		}
331*0Sstevel@tonic-gate	}
332*0Sstevel@tonic-gate
333*0Sstevel@tonic-gatesub main'label
334*0Sstevel@tonic-gate	{
335*0Sstevel@tonic-gate	if (!defined($label{$_[0]}))
336*0Sstevel@tonic-gate		{
337*0Sstevel@tonic-gate		$label{$_[0]}="\$${label}${_[0]}";
338*0Sstevel@tonic-gate		$label++;
339*0Sstevel@tonic-gate		}
340*0Sstevel@tonic-gate	return($label{$_[0]});
341*0Sstevel@tonic-gate	}
342*0Sstevel@tonic-gate
343*0Sstevel@tonic-gatesub main'set_label
344*0Sstevel@tonic-gate	{
345*0Sstevel@tonic-gate	if (!defined($label{$_[0]}))
346*0Sstevel@tonic-gate		{
347*0Sstevel@tonic-gate		$label{$_[0]}="\$${label}${_[0]}";
348*0Sstevel@tonic-gate		$label++;
349*0Sstevel@tonic-gate		}
350*0Sstevel@tonic-gate	if((defined $_[2]) && ($_[2] == 1))
351*0Sstevel@tonic-gate		{
352*0Sstevel@tonic-gate		push(@out,"$label{$_[0]}::\n");
353*0Sstevel@tonic-gate		}
354*0Sstevel@tonic-gate	else
355*0Sstevel@tonic-gate		{
356*0Sstevel@tonic-gate		push(@out,"$label{$_[0]}:\n");
357*0Sstevel@tonic-gate		}
358*0Sstevel@tonic-gate	}
359*0Sstevel@tonic-gate
360*0Sstevel@tonic-gatesub main'data_word
361*0Sstevel@tonic-gate	{
362*0Sstevel@tonic-gate	push(@out,"\tDD\t$_[0]\n");
363*0Sstevel@tonic-gate	}
364*0Sstevel@tonic-gate
365*0Sstevel@tonic-gatesub out1p
366*0Sstevel@tonic-gate	{
367*0Sstevel@tonic-gate	local($name,$p1)=@_;
368*0Sstevel@tonic-gate	local($l,$t);
369*0Sstevel@tonic-gate
370*0Sstevel@tonic-gate	push(@out,"\t$name\t ".&conv($p1)."\n");
371*0Sstevel@tonic-gate	}
372*0Sstevel@tonic-gate
373*0Sstevel@tonic-gatesub main'picmeup
374*0Sstevel@tonic-gate	{
375*0Sstevel@tonic-gate	local($dst,$sym)=@_;
376*0Sstevel@tonic-gate	&main'lea($dst,&main'DWP($sym));
377*0Sstevel@tonic-gate	}
378*0Sstevel@tonic-gate
379*0Sstevel@tonic-gatesub main'blindpop { &out1("pop",@_); }
380