• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/openssl-0.9.8e/crypto/perlasm/
1#!/usr/local/bin/perl
2
3package x86ms;
4
5$label="L000";
6
7%lb=(	'eax',	'al',
8	'ebx',	'bl',
9	'ecx',	'cl',
10	'edx',	'dl',
11	'ax',	'al',
12	'bx',	'bl',
13	'cx',	'cl',
14	'dx',	'dl',
15	);
16
17%hb=(	'eax',	'ah',
18	'ebx',	'bh',
19	'ecx',	'ch',
20	'edx',	'dh',
21	'ax',	'ah',
22	'bx',	'bh',
23	'cx',	'ch',
24	'dx',	'dh',
25	);
26
27sub main'asm_init_output { @out=(); }
28sub main'asm_get_output { return(@out); }
29sub main'get_labels { return(@labels); }
30sub main'external_label
31{
32	push(@labels,@_);
33	foreach (@_) {
34		push(@out, "EXTRN\t_$_:DWORD\n");
35	}
36}
37
38sub main'LB
39	{
40	(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
41	return($lb{$_[0]});
42	}
43
44sub main'HB
45	{
46	(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
47	return($hb{$_[0]});
48	}
49
50sub main'BP
51	{
52	&get_mem("BYTE",@_);
53	}
54
55sub main'DWP
56	{
57	&get_mem("DWORD",@_);
58	}
59
60sub main'QWP
61	{
62	&get_mem("QWORD",@_);
63	}
64
65sub main'BC
66	{
67	return @_;
68	}
69
70sub main'DWC
71	{
72	return @_;
73	}
74
75sub main'stack_push
76	{
77	local($num)=@_;
78	$stack+=$num*4;
79	&main'sub("esp",$num*4);
80	}
81
82sub main'stack_pop
83	{
84	local($num)=@_;
85	$stack-=$num*4;
86	&main'add("esp",$num*4);
87	}
88
89sub get_mem
90	{
91	local($size,$addr,$reg1,$reg2,$idx)=@_;
92	local($t,$post);
93	local($ret)="$size PTR ";
94
95	$addr =~ s/^\s+//;
96	if ($addr =~ /^(.+)\+(.+)$/)
97		{
98		$reg2=&conv($1);
99		$addr="_$2";
100		}
101	elsif ($addr =~ /^[_a-z][_a-z0-9]*$/i)
102		{
103		$addr="_$addr";
104		}
105
106	if ($addr =~ /^.+\-.+$/) { $addr="($addr)"; }
107
108	$reg1="$regs{$reg1}" if defined($regs{$reg1});
109	$reg2="$regs{$reg2}" if defined($regs{$reg2});
110	if (($addr ne "") && ($addr ne 0))
111		{
112		if ($addr !~ /^-/)
113			{ $ret.=$addr; }
114		else	{ $post=$addr; }
115		}
116	if ($reg2 ne "")
117		{
118		$t="";
119		$t="*$idx" if ($idx != 0);
120		$reg1="+".$reg1 if ("$reg1$post" ne "");
121		$ret.="[$reg2$t$reg1$post]";
122		}
123	else
124		{
125		$ret.="[$reg1$post]"
126		}
127	$ret =~ s/\[\]//;	# in case $addr was the only argument
128	return($ret);
129	}
130
131sub main'mov	{ &out2("mov",@_); }
132sub main'movb	{ &out2("mov",@_); }
133sub main'and	{ &out2("and",@_); }
134sub main'or	{ &out2("or",@_); }
135sub main'shl	{ &out2("shl",@_); }
136sub main'shr	{ &out2("shr",@_); }
137sub main'xor	{ &out2("xor",@_); }
138sub main'xorb	{ &out2("xor",@_); }
139sub main'add	{ &out2("add",@_); }
140sub main'adc	{ &out2("adc",@_); }
141sub main'sub	{ &out2("sub",@_); }
142sub main'sbb	{ &out2("sbb",@_); }
143sub main'rotl	{ &out2("rol",@_); }
144sub main'rotr	{ &out2("ror",@_); }
145sub main'exch	{ &out2("xchg",@_); }
146sub main'cmp	{ &out2("cmp",@_); }
147sub main'lea	{ &out2("lea",@_); }
148sub main'mul	{ &out1("mul",@_); }
149sub main'div	{ &out1("div",@_); }
150sub main'dec	{ &out1("dec",@_); }
151sub main'inc	{ &out1("inc",@_); }
152sub main'jmp	{ &out1("jmp",@_); }
153sub main'jmp_ptr { &out1p("jmp",@_); }
154sub main'je	{ &out1("je",@_); }
155sub main'jle	{ &out1("jle",@_); }
156sub main'jz	{ &out1("jz",@_); }
157sub main'jge	{ &out1("jge",@_); }
158sub main'jl	{ &out1("jl",@_); }
159sub main'ja	{ &out1("ja",@_); }
160sub main'jae	{ &out1("jae",@_); }
161sub main'jb	{ &out1("jb",@_); }
162sub main'jbe	{ &out1("jbe",@_); }
163sub main'jc	{ &out1("jc",@_); }
164sub main'jnc	{ &out1("jnc",@_); }
165sub main'jnz	{ &out1("jnz",@_); }
166sub main'jne	{ &out1("jne",@_); }
167sub main'jno	{ &out1("jno",@_); }
168sub main'push	{ &out1("push",@_); $stack+=4; }
169sub main'pop	{ &out1("pop",@_); $stack-=4; }
170sub main'pushf	{ &out0("pushfd"); $stack+=4; }
171sub main'popf	{ &out0("popfd"); $stack-=4; }
172sub main'bswap	{ &out1("bswap",@_); &using486(); }
173sub main'not	{ &out1("not",@_); }
174sub main'call	{ &out1("call",($_[0]=~/^\$L/?'':'_').$_[0]); }
175sub main'call_ptr { &out1p("call",@_); }
176sub main'ret	{ &out0("ret"); }
177sub main'nop	{ &out0("nop"); }
178sub main'test	{ &out2("test",@_); }
179sub main'bt	{ &out2("bt",@_); }
180sub main'leave	{ &out0("leave"); }
181sub main'cpuid  { &out0("DW\t0A20Fh"); }
182sub main'rdtsc  { &out0("DW\t0310Fh"); }
183sub main'halt	{ &out0("hlt"); }
184sub main'movz	{ &out2("movzx",@_); }
185sub main'neg	{ &out1("neg",@_); }
186sub main'cld	{ &out0("cld"); }
187
188# SSE2
189sub main'emms	{ &out0("emms"); }
190sub main'movd	{ &out2("movd",@_); }
191sub main'movq	{ &out2("movq",@_); }
192sub main'movdqu	{ &out2("movdqu",@_); }
193sub main'movdqa	{ &out2("movdqa",@_); }
194sub main'movdq2q{ &out2("movdq2q",@_); }
195sub main'movq2dq{ &out2("movq2dq",@_); }
196sub main'paddq	{ &out2("paddq",@_); }
197sub main'pmuludq{ &out2("pmuludq",@_); }
198sub main'psrlq	{ &out2("psrlq",@_); }
199sub main'psllq	{ &out2("psllq",@_); }
200sub main'pxor	{ &out2("pxor",@_); }
201sub main'por	{ &out2("por",@_); }
202sub main'pand	{ &out2("pand",@_); }
203
204sub out2
205	{
206	local($name,$p1,$p2)=@_;
207	local($l,$t);
208
209	push(@out,"\t$name\t");
210	$t=&conv($p1).",";
211	$l=length($t);
212	push(@out,$t);
213	$l=4-($l+9)/8;
214	push(@out,"\t" x $l);
215	push(@out,&conv($p2));
216	push(@out,"\n");
217	}
218
219sub out0
220	{
221	local($name)=@_;
222
223	push(@out,"\t$name\n");
224	}
225
226sub out1
227	{
228	local($name,$p1)=@_;
229	local($l,$t);
230
231	push(@out,"\t$name\t".&conv($p1)."\n");
232	}
233
234sub conv
235	{
236	local($p)=@_;
237
238	$p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
239	return $p;
240	}
241
242sub using486
243	{
244	return if $using486;
245	$using486++;
246	grep(s/\.386/\.486/,@out);
247	}
248
249sub main'file
250	{
251	local($file)=@_;
252
253	local($tmp)=<<"EOF";
254	TITLE	$file.asm
255        .386
256.model	FLAT
257_TEXT\$	SEGMENT PAGE 'CODE'
258
259EOF
260	push(@out,$tmp);
261	}
262
263sub main'function_begin
264	{
265	local($func,$extra)=@_;
266
267	push(@labels,$func);
268
269	local($tmp)=<<"EOF";
270PUBLIC	_$func
271$extra
272_$func PROC NEAR
273	push	ebp
274	push	ebx
275	push	esi
276	push	edi
277EOF
278	push(@out,$tmp);
279	$stack=20;
280	}
281
282sub main'function_begin_B
283	{
284	local($func,$extra)=@_;
285
286	local($tmp)=<<"EOF";
287PUBLIC	_$func
288$extra
289_$func PROC NEAR
290EOF
291	push(@out,$tmp);
292	$stack=4;
293	}
294
295sub main'function_end
296	{
297	local($func)=@_;
298
299	local($tmp)=<<"EOF";
300	pop	edi
301	pop	esi
302	pop	ebx
303	pop	ebp
304	ret
305_$func ENDP
306EOF
307	push(@out,$tmp);
308	$stack=0;
309	%label=();
310	}
311
312sub main'function_end_B
313	{
314	local($func)=@_;
315
316	local($tmp)=<<"EOF";
317_$func ENDP
318EOF
319	push(@out,$tmp);
320	$stack=0;
321	%label=();
322	}
323
324sub main'function_end_A
325	{
326	local($func)=@_;
327
328	local($tmp)=<<"EOF";
329	pop	edi
330	pop	esi
331	pop	ebx
332	pop	ebp
333	ret
334EOF
335	push(@out,$tmp);
336	}
337
338sub main'file_end
339	{
340	# try to detect if SSE2 or MMX extensions were used...
341	if (grep {/xmm[0-7]\s*,/i} @out) {
342		grep {s/\.[3-7]86/\.686\n\t\.XMM/} @out;
343		}
344	elsif (grep {/mm[0-7]\s*,/i} @out) {
345		grep {s/\.[3-7]86/\.686\n\t\.MMX/} @out;
346		}
347	push(@out,"_TEXT\$	ENDS\n");
348	push(@out,"END\n");
349	}
350
351sub main'wparam
352	{
353	local($num)=@_;
354
355	return(&main'DWP($stack+$num*4,"esp","",0));
356	}
357
358sub main'swtmp
359	{
360	return(&main'DWP($_[0]*4,"esp","",0));
361	}
362
363# Should use swtmp, which is above esp.  Linix can trash the stack above esp
364#sub main'wtmp
365#	{
366#	local($num)=@_;
367#
368#	return(&main'DWP(-(($num+1)*4),"esp","",0));
369#	}
370
371sub main'comment
372	{
373	foreach (@_)
374		{
375		push(@out,"\t; $_\n");
376		}
377	}
378
379sub main'public_label
380	{
381	$label{$_[0]}="_$_[0]"	if (!defined($label{$_[0]}));
382	push(@out,"PUBLIC\t$label{$_[0]}\n");
383	}
384
385sub main'label
386	{
387	if (!defined($label{$_[0]}))
388		{
389		$label{$_[0]}="\$${label}${_[0]}";
390		$label++;
391		}
392	return($label{$_[0]});
393	}
394
395sub main'set_label
396	{
397	if (!defined($label{$_[0]}))
398		{
399		$label{$_[0]}="\$${label}${_[0]}";
400		$label++;
401		}
402	if ($_[1]!=0 && $_[1]>1)
403		{
404		main'align($_[1]);
405		}
406	if((defined $_[2]) && ($_[2] == 1))
407		{
408		push(@out,"$label{$_[0]}::\n");
409		}
410	elsif ($label{$_[0]} !~ /^\$/)
411		{
412		push(@out,"$label{$_[0]}\tLABEL PTR\n");
413		}
414	else
415		{
416		push(@out,"$label{$_[0]}:\n");
417		}
418	}
419
420sub main'data_byte
421	{
422	push(@out,"\tDB\t".join(',',@_)."\n");
423	}
424
425sub main'data_word
426	{
427	push(@out,"\tDD\t".join(',',@_)."\n");
428	}
429
430sub main'align
431	{
432	push(@out,"\tALIGN\t$_[0]\n");
433	}
434
435sub out1p
436	{
437	local($name,$p1)=@_;
438	local($l,$t);
439
440	push(@out,"\t$name\t".&conv($p1)."\n");
441	}
442
443sub main'picmeup
444	{
445	local($dst,$sym)=@_;
446	&main'lea($dst,&main'DWP($sym));
447	}
448
449sub main'blindpop { &out1("pop",@_); }
450
451sub main'initseg
452	{
453	local($f)=@_;
454	local($tmp)=<<___;
455OPTION	DOTNAME
456.CRT\$XCU	SEGMENT DWORD PUBLIC 'DATA'
457EXTRN	_$f:NEAR
458DD	_$f
459.CRT\$XCU	ENDS
460___
461	push(@out,$tmp);
462	}
463
4641;
465