⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 milli64.s

📁 linux下的gcc编译器
💻 S
📖 第 1 页 / 共 5 页
字号:
/* 32 and 64-bit millicode, original author Hewlett-Packard   adapted for gcc by Paul Bame <bame@debian.org>   and Alan Modra <alan@linuxcare.com.au>.   Copyright 2001, 2002 Free Software Foundation, Inc.   This file is part of GNU CC and is released under the terms of   of the GNU General Public License as published by the Free Software   Foundation; either version 2, or (at your option) any later version.   See the file COPYING in the top-level GNU CC source directory for a copy   of the license.  */#ifdef pa64        .level  2.0w#endif/* Hardware General Registers.  */r0:	.reg	%r0r1:	.reg	%r1r2:	.reg	%r2r3:	.reg	%r3r4:	.reg	%r4r5:	.reg	%r5r6:	.reg	%r6r7:	.reg	%r7r8:	.reg	%r8r9:	.reg	%r9r10:	.reg	%r10r11:	.reg	%r11r12:	.reg	%r12r13:	.reg	%r13r14:	.reg	%r14r15:	.reg	%r15r16:	.reg	%r16r17:	.reg	%r17r18:	.reg	%r18r19:	.reg	%r19r20:	.reg	%r20r21:	.reg	%r21r22:	.reg	%r22r23:	.reg	%r23r24:	.reg	%r24r25:	.reg	%r25r26:	.reg	%r26r27:	.reg	%r27r28:	.reg	%r28r29:	.reg	%r29r30:	.reg	%r30r31:	.reg	%r31/* Hardware Space Registers.  */sr0:	.reg	%sr0sr1:	.reg	%sr1sr2:	.reg	%sr2sr3:	.reg	%sr3sr4:	.reg	%sr4sr5:	.reg	%sr5sr6:	.reg	%sr6sr7:	.reg	%sr7/* Hardware Floating Point Registers.  */fr0:	.reg	%fr0fr1:	.reg	%fr1fr2:	.reg	%fr2fr3:	.reg	%fr3fr4:	.reg	%fr4fr5:	.reg	%fr5fr6:	.reg	%fr6fr7:	.reg	%fr7fr8:	.reg	%fr8fr9:	.reg	%fr9fr10:	.reg	%fr10fr11:	.reg	%fr11fr12:	.reg	%fr12fr13:	.reg	%fr13fr14:	.reg	%fr14fr15:	.reg	%fr15/* Hardware Control Registers.  */cr11:	.reg	%cr11sar:	.reg	%cr11	/* Shift Amount Register *//* Software Architecture General Registers.  */rp:	.reg    r2	/* return pointer */#ifdef pa64mrp:	.reg	r2 	/* millicode return pointer */#elsemrp:	.reg	r31	/* millicode return pointer */#endifret0:	.reg    r28	/* return value */ret1:	.reg    r29	/* return value (high part of double) */sp:	.reg 	r30	/* stack pointer */dp:	.reg	r27	/* data pointer */arg0:	.reg	r26	/* argument */arg1:	.reg	r25	/* argument or high part of double argument */arg2:	.reg	r24	/* argument */arg3:	.reg	r23	/* argument or high part of double argument *//* Software Architecture Space Registers.  *//* 		sr0	; return link from BLE */sret:	.reg	sr1	/* return value */sarg:	.reg	sr1	/* argument *//* 		sr4	; PC SPACE tracker *//* 		sr5	; process private data *//* Frame Offsets (millicode convention!)  Used when calling other   millicode routines.  Stack unwinding is dependent upon these   definitions.  */r31_slot:	.equ	-20	/* "current RP" slot */sr0_slot:	.equ	-16     /* "static link" slot */#if defined(pa64)mrp_slot:       .equ    -16	/* "current RP" slot */psp_slot:       .equ    -8	/* "previous SP" slot */#elsemrp_slot:	.equ	-20     /* "current RP" slot (replacing "r31_slot") */#endif#define DEFINE(name,value)name:	.EQU	value#define RDEFINE(name,value)name:	.REG	value#ifdef milliext#define MILLI_BE(lbl)   BE    lbl(sr7,r0)#define MILLI_BEN(lbl)  BE,n  lbl(sr7,r0)#define MILLI_BLE(lbl)	BLE   lbl(sr7,r0)#define MILLI_BLEN(lbl)	BLE,n lbl(sr7,r0)#define MILLIRETN	BE,n  0(sr0,mrp)#define MILLIRET	BE    0(sr0,mrp)#define MILLI_RETN	BE,n  0(sr0,mrp)#define MILLI_RET	BE    0(sr0,mrp)#else#define MILLI_BE(lbl)	B     lbl#define MILLI_BEN(lbl)  B,n   lbl#define MILLI_BLE(lbl)	BL    lbl,mrp#define MILLI_BLEN(lbl)	BL,n  lbl,mrp#define MILLIRETN	BV,n  0(mrp)#define MILLIRET	BV    0(mrp)#define MILLI_RETN	BV,n  0(mrp)#define MILLI_RET	BV    0(mrp)#endif#ifdef __STDC__#define CAT(a,b)	a##b#else#define CAT(a,b)	a/**/b#endif#ifdef ELF#define SUBSPA_MILLI	 .section .text#define SUBSPA_MILLI_DIV .section .text.div,"ax",@progbits! .align 16#define SUBSPA_MILLI_MUL .section .text.mul,"ax",@progbits! .align 16#define ATTR_MILLI#define SUBSPA_DATA	 .section .data#define ATTR_DATA#define GLOBAL		 $global$#define GSYM(sym) 	 !sym:#define LSYM(sym)	 !CAT(.L,sym:)#define LREF(sym)	 CAT(.L,sym)#else#ifdef coff/* This used to be .milli but since link32 places different named   sections in different segments millicode ends up a long ways away   from .text (1meg?).  This way they will be a lot closer.   The SUBSPA_MILLI_* specify locality sets for certain millicode   modules in order to ensure that modules that call one another are   placed close together. Without locality sets this is unlikely to   happen because of the Dynamite linker library search algorithm. We   want these modules close together so that short calls always reach   (we don't want to require long calls or use long call stubs).  */#define SUBSPA_MILLI	 .subspa .text#define SUBSPA_MILLI_DIV .subspa .text$dv,align=16#define SUBSPA_MILLI_MUL .subspa .text$mu,align=16#define ATTR_MILLI	 .attr code,read,execute#define SUBSPA_DATA	 .subspa .data#define ATTR_DATA	 .attr init_data,read,write#define GLOBAL		 _gp#else#define SUBSPA_MILLI	 .subspa $MILLICODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,SORT=8#define SUBSPA_MILLI_DIV SUBSPA_MILLI#define SUBSPA_MILLI_MUL SUBSPA_MILLI#define ATTR_MILLI#define SUBSPA_DATA	 .subspa $BSS$,quad=1,align=8,access=0x1f,sort=80,zero#define ATTR_DATA#define GLOBAL		 $global$#endif#define SPACE_DATA	 .space $PRIVATE$,spnum=1,sort=16#define GSYM(sym)	 !sym#define LSYM(sym)	 !CAT(L$,sym)#define LREF(sym)	 CAT(L$,sym)#endif#ifdef L_dyncall	SUBSPA_MILLI	ATTR_DATAGSYM($$dyncall)	.export $$dyncall,millicode	.proc	.callinfo	millicode	.entry	bb,>=,n %r22,30,LREF(1)		; branch if not plabel address	depi	0,31,2,%r22		; clear the two least significant bits	ldw	4(%r22),%r19		; load new LTP value	ldw	0(%r22),%r22		; load address of targetLSYM(1)#ifdef LINUX	bv	%r0(%r22)		; branch to the real target#else	ldsid	(%sr0,%r22),%r1		; get the "space ident" selected by r22	mtsp	%r1,%sr0		; move that space identifier into sr0	be	0(%sr0,%r22)		; branch to the real target#endif	stw	%r2,-24(%r30)		; save return address into frame marker	.exit	.procend#endif#ifdef L_divI/* ROUTINES:	$$divI, $$divoI   Single precision divide for signed binary integers.   The quotient is truncated towards zero.   The sign of the quotient is the XOR of the signs of the dividend and   divisor.   Divide by zero is trapped.   Divide of -2**31 by -1 is trapped for $$divoI but not for $$divI.   INPUT REGISTERS:   .	arg0 ==	dividend   .	arg1 ==	divisor   .	mrp  == return pc   .	sr0  == return space when called externally   OUTPUT REGISTERS:   .	arg0 =	undefined   .	arg1 =	undefined   .	ret1 =	quotient   OTHER REGISTERS AFFECTED:   .	r1   =	undefined   SIDE EFFECTS:   .	Causes a trap under the following conditions:   .		divisor is zero  (traps with ADDIT,=  0,25,0)   .		dividend==-2**31  and divisor==-1 and routine is $$divoI   .				 (traps with ADDO  26,25,0)   .	Changes memory at the following places:   .		NONE   PERMISSIBLE CONTEXT:   .	Unwindable.   .	Suitable for internal or external millicode.   .	Assumes the special millicode register conventions.   DISCUSSION:   .	Branchs to other millicode routines using BE   .		$$div_# for # being 2,3,4,5,6,7,8,9,10,12,14,15   .   .	For selected divisors, calls a divide by constant routine written by   .	Karl Pettis.  Eligible divisors are 1..15 excluding 11 and 13.   .   .	The only overflow case is -2**31 divided by -1.   .	Both routines return -2**31 but only $$divoI traps.  */RDEFINE(temp,r1)RDEFINE(retreg,ret1)	/*  r29 */RDEFINE(temp1,arg0)	SUBSPA_MILLI_DIV	ATTR_MILLI	.import $$divI_2,millicode	.import $$divI_3,millicode	.import $$divI_4,millicode	.import $$divI_5,millicode	.import $$divI_6,millicode	.import $$divI_7,millicode	.import $$divI_8,millicode	.import $$divI_9,millicode	.import $$divI_10,millicode	.import $$divI_12,millicode	.import $$divI_14,millicode	.import $$divI_15,millicode	.export $$divI,millicode	.export	$$divoI,millicode	.proc	.callinfo	millicode	.entryGSYM($$divoI)	comib,=,n  -1,arg1,LREF(negative1)	/*  when divisor == -1 */GSYM($$divI)	ldo	-1(arg1),temp		/*  is there at most one bit set ? */	and,<>	arg1,temp,r0		/*  if not, don't use power of 2 divide */	addi,>	0,arg1,r0		/*  if divisor > 0, use power of 2 divide */	b,n	LREF(neg_denom)LSYM(pow2)	addi,>=	0,arg0,retreg		/*  if numerator is negative, add the */	add	arg0,temp,retreg	/*  (denominaotr -1) to correct for shifts */	extru,=	arg1,15,16,temp		/*  test denominator with 0xffff0000 */	extrs	retreg,15,16,retreg	/*  retreg = retreg >> 16 */	or	arg1,temp,arg1		/*  arg1 = arg1 | (arg1 >> 16) */	ldi	0xcc,temp1		/*  setup 0xcc in temp1 */	extru,= arg1,23,8,temp		/*  test denominator with 0xff00 */	extrs	retreg,23,24,retreg	/*  retreg = retreg >> 8 */	or	arg1,temp,arg1		/*  arg1 = arg1 | (arg1 >> 8) */	ldi	0xaa,temp		/*  setup 0xaa in temp */	extru,= arg1,27,4,r0		/*  test denominator with 0xf0 */	extrs	retreg,27,28,retreg	/*  retreg = retreg >> 4 */	and,=	arg1,temp1,r0		/*  test denominator with 0xcc */	extrs	retreg,29,30,retreg	/*  retreg = retreg >> 2 */	and,=	arg1,temp,r0		/*  test denominator with 0xaa */	extrs	retreg,30,31,retreg	/*  retreg = retreg >> 1 */	MILLIRETNLSYM(neg_denom)	addi,<	0,arg1,r0		/*  if arg1 >= 0, it's not power of 2 */	b,n	LREF(regular_seq)	sub	r0,arg1,temp		/*  make denominator positive */	comb,=,n  arg1,temp,LREF(regular_seq)	/*  test against 0x80000000 and 0 */	ldo	-1(temp),retreg		/*  is there at most one bit set ? */	and,=	temp,retreg,r0		/*  if so, the denominator is power of 2 */	b,n	LREF(regular_seq)	sub	r0,arg0,retreg		/*  negate numerator */	comb,=,n arg0,retreg,LREF(regular_seq) /*  test against 0x80000000 */	copy	retreg,arg0		/*  set up arg0, arg1 and temp	*/	copy	temp,arg1		/*  before branching to pow2 */	b	LREF(pow2)	ldo	-1(arg1),tempLSYM(regular_seq)	comib,>>=,n 15,arg1,LREF(small_divisor)	add,>=	0,arg0,retreg		/*  move dividend, if retreg < 0, */LSYM(normal)	subi	0,retreg,retreg		/*    make it positive */	sub	0,arg1,temp		/*  clear carry,  */					/*    negate the divisor */	ds	0,temp,0		/*  set V-bit to the comple- */					/*    ment of the divisor sign */	add	retreg,retreg,retreg	/*  shift msb bit into carry */	ds	r0,arg1,temp		/*  1st divide step, if no carry */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  2nd divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  3rd divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  4th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  5th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  6th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  7th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  8th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  9th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  10th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  11th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  12th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  13th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  14th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  15th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  16th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  17th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  18th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  19th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  20th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  21st divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  22nd divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  23rd divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  24th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  25th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  26th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  27th divide step */	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */	ds	temp,arg1,temp		/*  28th divide step */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -