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

📄 emulate.s

📁 早期freebsd实现
💻 S
📖 第 1 页 / 共 3 页
字号:
	jbr	L220L219:					# else put fill character	putfillL220:	sobgtr	r1,L214	jbr	Ledit_caseLe_float:				# move with floating sign character	tstl	r1	jeql	Ledit_caseL221:	jlbc	r2,L222	extzv	$4,$4,(r10),r11	jbr	L223L222:	extzv	$0,$4,(r10),r11	incl	r10L223:	decl	r2			# source length CAN go negative here...	tstl	r11	jeql	L225	jbs	SIGNIFBIT,r4,L226	putsignL226:	setsignifL225:	jbc	SIGNIFBIT,r4,L227	addb3	$48,r11,(r5)+	jbr	L228L227:	putfillL228:	sobgtr	r1,L221	jbr	Ledit_case	.align	1	.globl	_EMashp_EMashp:	argb(1,r11)		# (1) scale (number to shift) == r11	arguw(2,r10)		# (2) source length == r10	argl(3,r1)		# (3) source address == r1	argub(4,r2)		# (4) rounding factor == r2	arguw(5,r3)		# (5) destination length == r3	toarg(r6,3)	# arg3 holds register 6 from caller	argl(6,r6)		# (6) destination address == r6			# we need arg6 for later			# arg1 is used for temporary storage			# arg2 holds "even or odd" destination length			# arg4 is used as general storage			# arg5 is used as general storage	ashl	$-1,r3,r0	# destination length is number of bytes	addl2	r0,r6		# destination address == least sig nibble	toarg(r6,1)		# save in arg1 spot for later	ashl	$-1,r10,r0	addl2	r0,r1		# source address == least sig nibble	extzv	$0,$4,(r1),r0	# determine sign of source	cmpl	r0,NEGATIVEalt	jeql	Lashp_neg	cmpl	r0,NEGATIVE	jeql	Lashp_neg	movb	POSITIVE,(r6)	jbr	L245Lashp_neg:	movb	NEGATIVE,(r6)L245:	clrl	arg2		# arg2 is 1 if dstlen is even, 0 if odd	blbs	r3,L246	incl	arg2	bisl2	$1,r3		# r3<0> counts digits going into destinationL246:				#	and is flip-flop for which nibble to	tstl	r11		#	write in destination (1 = high, 0 = low)	jgeq	Lashp_left	#	(it must start out odd)	addl2	r11,r10		# scale is negative (right shift)	jgeq	Lashp_right	clrl	r10		# test for shifting whole number out	jbr	Lashp_setroundLashp_right:	divl3	$2,r11,r0	addl2	r0,r1		# source address == MSNibble to be shifted off	jlbc	r11,L249	extzv	$4,$4,(r1),r0	addl2	r0,r2		# round = last nibble to be shifted off + round	jbr	Lashp_setroundL249:	extzv	$0,$4,(r1),r0	addl2	r0,r2		# round = last nibble to be shifted off + roundLashp_setround:			# r11<0> now is flip-flop for which nibble to	incl	r11		#    read from source (1 == high, 0 == low)	cmpl	r2,$9		# set rounding factor to one if nibble shifted	jleq	Lashp_noround	#    off + round argument was 10 or greater	movl	$1,r2	jbr	Lashp_shiftLashp_zloop:	jlbs	r3,L257		# don't need to clear high nibble twice	clrb	-(r6)		# clear low (and high) nib of next byte in destL257:	sobgtr	r3,L258		# move to next nibble in destination, but	incl	r3		#	don't go beyond the end.L258:	decl	r11Lashp_left:			# while scale is positive	jneq	Lashp_zloop	incl	r11		# r11<0> is flip-plop ... (incl sets it to one)Lashp_noround:	clrl	r2		# no more roundingLashp_shift:	clrl	arg4		# arg4 will be used for result condition codes	tstl	r10	jeql	Lashp_roundLashp_shloop:	jlbc	r11,L260	extzv	$4,$4,(r1),r0	jbr	L261L260:	decl	r1	extzv	$0,$4,(r1),r0L261:	incl	r11		# flip the source nibble flip/flop	addl2	r0,r2		# round += next nibble	cmpl	r2,$10		# if round == 10	jneq	L262	clrl	arg5		#	then result = 0 and round = 1	movl	$1,r2	jbr	L263L262:				# else	movl	r2,arg5		#	store result and round = 0	clrl	r2L263:	bisl2	arg5,arg4	# remember if result was nonzero in arg4	decl	r3		# move to next nibble early to check	cmpl	r3,arg2		# if we've moved passed destination limits	jgeq	Lashp_noovfl	#	test the result for possible overflow	movl	arg2,r3		#	ignore zero nibbles	tstl	arg5		#	if the nibble was non-zero, overflow	jeql	L265	jbr	Lashp_overflLashp_noovfl:			# else	jlbs	r3,L264	insv	arg5,$4,$4,(r6)	# put the result into destination (high or low)	jbr	L265L264:	movb	arg5,-(r6)L265:	sobgtr	r10,Lashp_shloop	# loop for length of sourceLashp_round:	tstl	r2		# take care of round out of high nibble	jeql	Lashp_zeroround	decl	r3	cmpl	r3,arg2		# if we've moved passed destination limits	jlss	Lashp_overfl	#	then overflow	jlbs	r3,L266	insv	arg5,$4,$4,(r6)	# put the round into destination (high or low)	jbr	Lashp_zeroroundL266:	movb	arg5,-(r6)Lashp_zeroround:	argl(1,r10)		# r10 = address of destination LSNibble	argl(6,r3)		# r3 = address of destination MSNibble	movl	arg4,r11	# r11 = non-zero if destination == non-zero	savepsl	jbr	L267Lashp_zerofill:	clrb	-(r6)		# fill up MSNs of destination with zerosL267:	cmpl	r3,r6	jneq	Lashp_zerofill	extzv	$0,$4,(r10),r0	# test for negative result	cmpl	r0,NEGATIVE	jneq	Lashp_out	mnegl	r11,r11	savepsl	jneq	Lashp_out	# turn -0 into 0	insv	POSITIVE,$0,$4,(r10)Lashp_out:	clrl	r0	argl(3,r6)		# restore r6 from stack	returnLashp_overfl:			#    do overflow	clrl	r2	overflowpsl	jbr	Lashp_out	.align	1	.globl	_EMcvtlp_EMcvtlp:	arguw(2,r10)		# (2) destination length == r10	argl(3,r3)		# (3) destination address == r3	ashl	$-1,r10,r10	addl2	r10,r3		# destination address points to Least Sig byte	incl	r10		# length is # of bytes, not nibbles	argl(1,r11)		# (1) source == r11	savepsl	jgeq	Lcvtlp_pos	movb	NEGATIVE,(r3)	# source is negative	divl3	$10,r11,r0	mull3	$10,r0,r1	subl3	r11,r1,r2	# r2 = source mod 10	mnegl	r0,r11		# source = -(source / 10)	jbr	Lcvtlp_cvtLcvtlp_pos:	movb	POSITIVE,(r3)	# source is non-negative	divl3	$10,r11,r0	mull3	$10,r0,r1	subl3	r1,r11,r2	# r2 = source mod 10	movl	r0,r11		# source = source / 10Lcvtlp_cvt:	insv	r2,$4,$4,(r3)	# store least significant digit	tstl	r11	jeql	Lcvtlp_zloopLcvtlp_loop:			# while source is non-zero	decl	r10		#   and for length of destination ...	jeql	Lcvtlp_over	divl3	$10,r11,r1	# r1 = source / 10	mull3	$10,r1,r0	subl2	r0,r11		# source = source mod 10	movb	r11,-(r3)	# store low "nibble" in next significant byte	divl3	$10,r1,r11	# source = r1 / 10	mull3	$10,r11,r0	subl2	r0,r1		# r1 = source mod 10	insv	r1,$4,$4,(r3)	# store high nibble	tstl	r11	jneq	Lcvtlp_loop	# quit if source becomes zeroLcvtlp_zloop:			# fill any remaining bytes with zeros	decl	r10	jeql	Lcvtlp_out	clrb	-(r3)	jbr	Lcvtlp_zloopLcvtlp_over:	overflowpslLcvtlp_out:	clrl	r1		# r0 is already zero	clrl	r2	return	.align	1	.globl	_EMcvtpl_EMcvtpl:	arguw(1,r11)		# (1) source length == r11	argl(2,r10)		# (2) source address == r10	clrl	r3		# r3 == destination	movl	r10,r1		# r1 set up now for return	ashl	$-1,r11,r11	# source length is number of bytes	jeql	Lcvtpl_zeroLcvtpl_loop:			# for source length	mull2	$10,r3		# destination *= 10	extzv	$4,$4,(r10),r0	addl2	r0,r3		# destination += high nibble	mull2	$10,r3		# destination *= 10	extzv	$0,$4,(r10),r0	addl2	r0,r3		# destination += low nibble	incl	r10	sobgtr	r11,Lcvtpl_loopLcvtpl_zero:			# least significant byte	mull2	$10,r3	extzv	$4,$4,(r10),r0	addl2	r0,r3		# dest = 10 * dest + high nibble	savepsl	extzv	$0,$4,(r10),r2	# test sign nibble	cmpl	r2,NEGATIVE	jeql	Lcvtpl_neg	cmpl	r2,NEGATIVEalt	jneq	Lcvtpl_outLcvtpl_neg:			# source was negative - negate destination	mnegl	r3,r3	savepslLcvtpl_out:	toarg(r3,3)	clrl	r0	clrl	r2	clrl	r3	return	.align	1	.globl	_EMcvtps_EMcvtps:	return	.align	1	.globl	_EMcvtsp_EMcvtsp:	return	.align	1	.globl	_EMaddp6_EMaddp6:	return	.align	1	.globl	_EMsubp4_EMsubp4:	return	.align	1	.globl	_EMsubp6_EMsubp6:	return	.align	1	.globl	_EMcvtpt_EMcvtpt:	return	.align	1	.globl	_EMmulp_EMmulp:	return	.align	1	.globl	_EMcvttp_EMcvttp:	return	.align	1	.globl	_EMdivp_EMdivp:	return	.align	1	.globl	_EMcmpp3_EMcmpp3:	return	.align	1	.globl	_EMcmpp4_EMcmpp4:	return#endif UVAXII#ifdef notdef/* * Emulation OpCode jump table: *	ONLY GOES FROM 0xf8 (-8) TO 0x3B (59) */#define EMUTABLE	0x43#define NOEMULATE	.long noemulate#define	EMULATE(a)	.long _EM/**/a	.globl	_emJUMPtable_emJUMPtable:/* f8 */	EMULATE(ashp);	EMULATE(cvtlp);	NOEMULATE;	NOEMULATE/* fc */	NOEMULATE;	NOEMULATE;	NOEMULATE;	NOEMULATE/* 00 */	NOEMULATE;	NOEMULATE;	NOEMULATE;	NOEMULATE/* 04 */	NOEMULATE;	NOEMULATE;	NOEMULATE;	NOEMULATE/* 08 */	EMULATE(cvtps);	EMULATE(cvtsp);	NOEMULATE;	EMULATE(crc)/* 0c */	NOEMULATE;	NOEMULATE;	NOEMULATE;	NOEMULATE/* 10 */	NOEMULATE;	NOEMULATE;	NOEMULATE;	NOEMULATE/* 14 */	NOEMULATE;	NOEMULATE;	NOEMULATE;	NOEMULATE/* 18 */	NOEMULATE;	NOEMULATE;	NOEMULATE;	NOEMULATE/* 1c */	NOEMULATE;	NOEMULATE;	NOEMULATE;	NOEMULATE/* 20 */	EMULATE(addp4);	EMULATE(addp6);	EMULATE(subp4);	EMULATE(subp6)/* 24 */	EMULATE(cvtpt);	EMULATE(mulp);	EMULATE(cvttp);	EMULATE(divp)/* 28 */	NOEMULATE;	EMULATE(cmpc3);	EMULATE(scanc);	EMULATE(spanc)/* 2c */	NOEMULATE;	EMULATE(cmpc5);	EMULATE(movtc);	EMULATE(movtuc)/* 30 */	NOEMULATE;	NOEMULATE;	NOEMULATE;	NOEMULATE/* 34 */	EMULATE(movp);	EMULATE(cmpp3);	EMULATE(cvtpl);	EMULATE(cmpp4)/* 38 */	EMULATE(editpc); EMULATE(matchc); EMULATE(locc); EMULATE(skpc)/* * The following is called with the stack set up as follows: * *	  (sp):	Opcode *	 4(sp):	Instruction PC *	 8(sp):	Operand 1 *	12(sp):	Operand 2 *	16(sp):	Operand 3 *	20(sp):	Operand 4 *	24(sp):	Operand 5 *	28(sp):	Operand 6 *	32(sp):	Operand 7 (unused) *	36(sp):	Operand 8 (unused) *	40(sp):	Return PC *	44(sp):	Return PSL *	48(sp): TOS before instruction * * Each individual routine is called with the stack set up as follows: * *	  (sp):	Return address of trap handler *	 4(sp):	Opcode (will get return PSL) *	 8(sp):	Instruction PC *	12(sp):	Operand 1 *	16(sp):	Operand 2 *	20(sp):	Operand 3 *	24(sp):	Operand 4 *	28(sp):	Operand 5 *	32(sp):	Operand 6 *	36(sp):	saved register 11 *	40(sp):	saved register 10 *	44(sp):	Return PC *	48(sp):	Return PSL *	52(sp): TOS before instruction */SCBVEC(emulate):	movl	r11,32(sp)		# save register r11 in unused operand	movl	r10,36(sp)		# save register r10 in unused operand	cvtbl	(sp),r10		# get opcode	addl2	$8,r10			# shift negative opcodes	subl3	r10,$EMUTABLE,r11	# forget it if opcode is out of range	bcs	noemulate	movl	_emJUMPtable[r10],r10	# call appropriate emulation routine	jsb	(r10)		# routines put return values into regs 0-5	movl	32(sp),r11		# restore register r11	movl	36(sp),r10		# restore register r10	insv	(sp),$0,$4,44(sp)	# and condition codes in Opcode spot	addl2	$40,sp			# adjust stack for return	reinoemulate:	addl2	$48,sp			# adjust stack for	.word	0xffff			# "reserved instruction fault"SCBVEC(emulateFPD):	.word	0xffff			# "reserved instruction fault"#endif

⌨️ 快捷键说明

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