35.2.1.1. АРИФМЕТИЧЕСКИЕ КОМАНДЫ



Addition

Сложение




	destination = source1 + source2;
Операция складывает два своих операнда (source1 и source2) и помещает результат в destination. Поскольку данные представлены в дополнительном коде, то команда обслуживает сразу и signed и unsigned числа. Как правило непосредственные (immediate) (числовые) операнды содержаться в команде как sign-extended числа. CISC-based процессоры как правило имеют отдельные формы команд для всех размеров операндов. Для RISC машин как правило характерно выполнение таких команд сразу над регистрами соответсвующими разрядности процессора (например 64-бит), при этом подразумевается, что если вам нужны результаты меньшей разрядности (например 32), то вы должны предварительно подготовить в регистрах sign-extended до нужного числа бит (например 64) версии операндов. Но есть и исключения (например Alpha ADDL) Как правило Addition модифицирует все основные арифметические флаги (carry, zero, sign, overflow). Но существуют процессоры (например PowerPC), которые имеют версии команд которые модифицируют флаги (add.), и которые не модифицируют (add). А есть процессоры которые вообще не ставят флаги после операций. Некоторые процесоры (HPPA, ARM, IA64) могут выполнять данную команду по определенным условиям. Некоторые процессоры при определенных условиях могут вызывать Trap при возникновении переполнения (при операциям с signed integer). Для других процессоров отслеживание signed переполнения и вызов соответсвующего Trap требуют дополнительных команд, например x86:
	add	ax,bx
	into         	; Trap if overflow flag set
Для отслеживания необязательно использовать Trap, можно использовать и условных переход по флагу переполнения (если он конечно есть)
	add	eax,ebx
	jo	label	; Conditionalm Jump if Overflow
-------------------------------------------------------------------------- o Unsigned/Signed Addition w/o Carry x86 ADD 8 RR add rd,rs 86 8 RI{8S} add rd,imm 86 16 RR 86 16 RI{8S,16} 86 32 RR 386 32 RI{8S,32} 386 ------------------------------------ Alpha ADDL 32 RRR addl ra,rb,rc 21064 rc = sext(ra[31..0] + rb[31..0]) 32 RRI{8S} 21064 addl ra,#imm,rc ADDQ 64 RRR addq ra,rb,rc 21064 rc = ra + rb 64 RRI{8S} addq ra,#imm,rc 21064 ------------------------------------ PPC ADD max RRR add rD,rA,rB rD = rA + rB ADD. max RRR [set flags] ADDO max RRR [check overflow] ADDO. max RRR [set flags,set overflow] ADDI max RRI{16S} addi rD,rA,IMM ------------------------------------ MIPS ADD 32 RRR add rd,rs,rt MIPS I rd = rs + rt Trap if overflow ADDI 32 RRI{16S} addi rt,rs,imm MIPS I rt = rs + imm Trap if overflow ADDIU 32 RRI{16S} addiu rt,rs,imm MIPS I rt = rs + imm ADDU 32 RRR addu rd,rs,rt MIPS I rd = rs + rt DADD 64 RRR dadd rd,rs,rt MIPS III rd = rs + rt Trap if overflow DADDI 64 RRI{16S} daddi rt,rs,imm MIPS III rt = rs + imm Trap if overflow DADDIU 64 RRI{16S} daddiu rt,rs,imm MIPS III rt = rs + imm DADDU 64 RRR daddu rd,rs,rt MIPS III rd = rs + rt ------------------------------------ SPARC ADD max RRR add rs1,rs2,rd V8 max RRI{13S} add rs1,imm,rd V8 ADDcc max RRR addcc rs1,rs2,rd V8 [Modify condition codes] max RRI{13S} addcc rs1,imm,rd V8 ------------------------------------ 68K ADD 8 RR (D-regs) 16 RR 32 RR ADDA 16 RR (A-regs) 32 RR ADDI 8 RI (A-,D- regs) 16 RI [ADDQ - nibble] 32 RI ------------------------------------ z80 ADD 8 AR AI 16 AR ------------------------------------ HPPA ADDc 32 RRR ADDLc 32 RRR (Not Affect PSW C/B-bit) ADDIc 32 I11,RR ADDIL 32 I21,R ------------------------------------ VAX-11 ADDB2 8 RR ADDB3 8 RRR ADDW2 16 RR ADDW3 16 RRR ADDL2 32 RR ADDL3 32 RRR ------------------------------------ IA-64 ADD 64 R,R,R ADDS 64 R,R,I14 ADDL 64 R,R,I22 ------------------------------------ MCS51 ADD 8 AR 8 AM 8 AI ------------------------------------ JVM IADD 32 LADD 64 ------------------------------------ ARM ADDcc 32 RRR RRI ------------------------------------ SH4 ADD RR RI ADDV RR (set overflow flag)


Addition with Carry

Сложение с флагом переноса

	destination = source1 + source2 + CF;
Операция складывает два своих операнда и Carry Flag и помещает результат в destination. Эта команда черезвычайна важна для выполнения вычислений с арифметикой большой точности. (Смотри раздел 41.2) Процессоры которые не поддерживают такую команду напрямую могут ее эмулировать выполняя установку регистра в 0 или 1 в зависимости от условия, и последущего сложения затем. Но если нам нужна просто арифметика расширенной точности, то Собсвенно подсказкой для работы в дополнительном коде, служит: Carry flag устанавливается когда: result = X + Y < X P + P = P no carry P + P = N no carry P + N = N no carry P + N = P carry N + P = P carry N + P = N no carry N + N = N carry N + N = P carry Процессоры Alpha не поддерживают такую команду. Действие выполняемое командой реализуется через следующую последовательность команд: cmovlt TODO: Check this sequence - this sequence is wrong ! R1:R2 = R3:R4 + R5:R6 addq r4,r6,r2 ! r2 = r4 + r6 subq r2,r4,r7 ! r7 = r6 and r31,r31,r8 ! r8 = 0 cmovlt r7,1,r8 ! r8 = carry (r7 < 0)? 1: 0 addq r3,r5,r1 ! add high part addq r1,r8,r1 ! add carry to high part Процессоры MIPS не поддерживают такую команду. Действие реализуемое командой можно реализовать через сложную последовательность включающую
	; R1:R2 = R3:R4 + R5:R6
	; used R7
	add	r2,r4,r6
	sltu	r7,r2,r4
	add	r1,r3,r5
	add	r1,r1,r7
IA-64 поддерживает форму команды сложения add r1=r2,r3,1 Поскольку IA-64 содержит предикаты выполнения то аналог сложения с Carry будет пара команд (p1) r1=r2,r3,1 (p2) r1=r2,r3 ;; при условии что предикаты выставлены ранее.
	// Addition:  R1:R2 = R3:R4 + R5:R6
	add	r2 = r4,r6
	;;
	cmp.ltu	p1,p2 = r2,r4
	;;
(p1)	add	r1 = r3,r5,1
(p2)	add	r1 = r2,r5
--------------------------------------------------------------------------- o Unsigned/Signed Addition with Carry x86 ADC 8 RR RI 16 RR RI 32 RR RI ------------------------------------ Alpha (*) CMOVxx + ADDxx ------------------------------------ PPC ADDC max RRR ADDIC max RRR ------------------------------------ MIPS (*) ADDU/ADDIU Look !!! ------------------------------------ SPARC ADDX max RRR RRI ------------------------------------ 68K ADDX 8 RR (D-regs) 16 RR 32 RR ------------------------------------ z80 ADC 8 AR AI 16 AR ------------------------------------ HPPA ADDCc 32 RRR ------------------------------------ VAX-11 ADWC 32 RR ------------------------------------ IA-64 ADD 64 RRR1 (*) More complex ------------------------------------ MCS51 ADDC 8 AR AM AI ------------------------------------ ARM ADCcc 32 RRR RRI ------------------------------------ SH4 ADDC RR


Addition Scale/Index/Base



	destination = source1 + source2 * scale
Команда используется для вычисления адрессов в массивах. Scale - фиксированная константа (кратная степени 2 - как правило 2,4,8). Преймущество команды в том что она быстрая, в отличии от пары сложение+сдвиг, и тем более сложение+обычное_умножение. На x86 команда использует мнемонику ориентированную на доступ к памяти, но реально команда не обращается к памяти, а просто вычисляет адресс, который и записывается в destination register. Это пример разумного использования AGU для оптимизации вычислений.
	lea	eax,[ebx + ecx * 8 + 1234h]
На процессорах не имеющих такой команды, эту функциональность можно реализовать комбинацией команд сдвига и сложения. --------------------------------------------------------------------------- o Unsigned Addition Scale/Index/Base x86 LEA 32 RRR scale = 2,4,8 ------------------------------------- Alpha S4ADDL 32 RRR RRI scale = 4 S8ADDL 32 RRR RRI scale = 8 S4ADDQ 64 RRR RRI scale = 4 S8ADDQ 64 RRR RRI scale = 8 ------------------------------------- PPC (*) Complex Sequence ------------------------------------- MIPS (*) Complex Sequence ------------------------------------- 68K (*) Complex sequence ------------------------------------- z80 (*) Complex sequence ------------------------------------- HPPA SH1ADD 32 RRR scale = 2 SH1ADDL 32 RRR scale = 2 (Not affect PSW C/B) SH2ADD 32 RRR scale = 4 SH2ADDL 32 RRR scale = 4 (Not affect PSW C/B) SH3ADD 32 RRR scale = 8 SH3ADDL 32 RRR scale = 8 (Not affect PSW C/B)


Subtract

Вычитание

	destination = source1 - source2
Команда вычитает один свой операнд из другого и помещает результат в destination. Поскольку данные представлены в дополнительном коде, то команда обслуживает сразу и signed и unsigned числа. Читай замечания для Addition
PowerPC поддерживают интересную операцию subfic:


которая вычитает source операнд из нуля, что бывает часто полезно.
--------------------------------------------------------------------------- o Unsigned/Signed General Integer Subtractions w/o Carry x86 SUB 8 RR RI 16 RR RI 32 RR RI ------------------------------------- Alpha SUBL 32 RRR RRI SUBQ 64 RRR RRI ------------------------------------- PPC SUBF max RRR SUBFI max RRI ------------------------------------- MIPS SUB 32 RRR DSUB 64 RRR ------------------------------------- SPARC SUB max RRR RRI ------------------------------------- 68K SUB 8 RR (D-regs) 16 RR 32 RR SUBA 8 RR (A-regs) 16 RR 32 RR SUBI 8 RI (A-,D- regs) 16 RI [SUBQ - nibble] 32 RI -------------------------------------- z80 SUB 8 AR AI -------------------------------------- HPPA SUBc 32 RRR SUBIc 32 I11,RR -------------------------------------- VAX-11 SUBB2 8 RR SUBB3 8 RRR SUBW2 16 RR SUBW3 16 RRR SUBL2 32 RR SUBL3 32 RRR -------------------------------------- IA-64 SUB max R1=R2,R3 max R1=I8,R3 max R1=R2,R3,1 --------------------------------------- MCS51 (*) Complex --------------------------------------- JVM ISUB 32 LSUB 64 --------------------------------------- ARM SUBcc 32 RRR RRI RSBcc 32 RRR RRI --------------------------------------- SH4 SUB RR SUBV RR (set overflow)


Subtract with Borrow

Вычитание с заемом

	destination = source1 - source2 - CF
Команда вычитает один свой операнд из другого, вычитает еще Carry Flag и помещает результат в destination. Эта команда черезвычайна важна для выполнения вычислений с арифметикой большой точности. (Смотри раздел 41.2) Процессоры Alpha не поддерживают такую команду. Действие выполняемое командой реализуется через следующую последовательность команд: cmov ult форма subq Аналогично MIPS. Смотри также комментарии к Addition. -------------------------------------------------------------------- o Unsigned/Signed General Integer Subtraction with Borrow x86 SBC 8 RR RI 16 RR RI 32 RR RI ------------------------------------- Alpha (*) CMOVxx + SUBLxx ------------------------------------- PPC SUBFC max RRR SUBFIC max RRI -------------------------------------- MIPS (*) SUBU/DSUBU ??? -------------------------------------- SPARC SUBX max RRR RRI -------------------------------------- 68K SUBX 8 RR (D-regs) 16 RR 32 RR -------------------------------------- z80 SBC 8 AR AI 16 AR -------------------------------------- HPPA SUBBc 32 RRR -------------------------------------- MCS51 SUBB 8 AR AM AI -------------------------------------- ARM SBCcc 32 RRR RRI RSCcc 32 RRR RRI -------------------------------------- SH4 SUBC RR


Subtract Scale/Index/Base



	destination = source1 - source2 * scale
Команда используется для вычисления адрессов в массивах. Scale - фиксированная константа (кратная степени 2 - как правило 2,4,8). Преймущество команды в том что она быстрая, в отличии от пары сложение+сдвиг, и тем более сложение+обычное_умножение. ----------------------------------------------------------------------------- o Unsigned subtraction Scale/Index/Base x86 (*) Complex sequence --------------------------------------- Alpha S4SUBL 32 RRR RRI (scale = 4) S8SUBL 32 RRR RRI (scale = 8) S4SUBQ 64 RRR RRI (scale = 4) S8SUBQ 64 RRR RRI (scale = 8) ---------------------------------------- PPC (*) Complex sequence ---------------------------------------- MIPS (*) Complex sequence ---------------------------------------- 68K (*) Complex sequence ---------------------------------------- z80 (*) Complex sequence ---------------------------------------- HPPA (*) see Unsigned addition Scale/Index/Base


Unsigned Multiply

	destination = source1 (unsigned *) source2
Команда выполняет умножение операндов. Возможные формы команды:
MULU 	Multiply Unsigned   		XX * XX -> XXXX


Беззнаково умножает два операнда и помещает результат в destination, который имеет размер в 2 раза больше чем каждый из операндов.


MULL	Multiply Low (Signed/Unsigned)  XX * XX -> LOW(XXXX) = XX





Для дополнительного кода младшая половина результата умножения, который имеет размер равный удвоенному размеру каждого из операндов - одинакова и для знакового и для беззнакового умножения.


MULHU	Multiply High Unsigned		XX * XX -> HIGH(XXXX) = XX





Беззнаково умножает операнды и возвращает старшую часть результата.


Как правило процессоры имеют либо инструкцию типа MULU (результат часто может записываться только в определенные регистры (пример: x86: EDX:EAX, MIPS: HI:LO)), либо набор MULL и пару MULH - одну для знакового, другое для беззнакового умножения. При полном умножении MULU или при MULHU переполнение не может возникнуть, поэтому OF=0 ------------------------------------------------------------------------------ o Unsigned Integer Multiply x86 MUL 8 AccR ( 8x8 -> 16) 16 AccR (16x16 -> 32) 32 AccR (32x32 -> 64) ---------------------------------------- Alpha UMULH 64 RRR RRI (64x64 -> 128 (high)) MULQ 64 RRR RRI (64x64 -> 128 (low))) ---------------------------------------- PPC MULHWU 32 RRR (32x32 -> 64 (high)) MULL 32 RRR (32x32 -> 64 (low)) MULHDU 64 RRR (64x64 -> 128 (high)) MULLD 64 RRR (64x64 -> 128 (low)) ---------------------------------------- MIPS MULTU 32 AccR (32x32 -> 64) (HI,LO) DMULTU 64 AccR (64x64 -> 128) (HI,LO) ---------------------------------------- SPARC UMUL 32 RRR RRI MULX 64 RRR V9 (Generic 64bit Mul) ---------------------------------------- 68K MULU 16 RR (D-regs) (16x16 -> 32) 32 RR (32x32 -> 32) ?? ---------------------------------------- z80 (*) Complex sequence ---------------------------------------- HPPA ??? ---------------------------------------- VAX-11 ??? MULB2 8 RR MULB3 8 RRR MULW2 16 RR MULW3 16 RRR MULL2 32 RR MULL3 32 RRR ----------------------------------------- MCS51 MUL 8 AB (BA <- A x B) ----------------------------------------- ARM UMULLcc 32 RRRR (32:32 <- 32 * 32) ----------------------------------------- SH4 MULU.W RR (16x16 -> 32) DMULU.L RR (32x32 -> 64)


HP-PA Multiply:


#ifdef L_multiply
#define	op0	%r26
#define	op1	%r25
#define res	%r29
#define ret	%r31
#define tmp	%r1

SPACE
GSYM($$mulU)
GSYM($$mulI)
	.proc
	.callinfo	frame=0,no_calls
	.entry
	addi,tr		0,%r0,res	; clear out res, skip next insn
LSYM(loop)
	zdep		op1,26,27,op1	; shift up op1 by 5
LSYM(lo)
	zdep		op0,30,5,tmp	; extract next 5 bits and shift up
	blr		tmp,%r0
	extru		op0,26,27,op0	; shift down op0 by 5
LSYM(0)
	comib,<>	0,op0,LREF(lo)
	zdep		op1,26,27,op1	; shift up op1 by 5
	bv		%r0(ret)
	nop
LSYM(1)
	b		LREF(loop)
	addl		op1,res,res
	nop
	nop
LSYM(2)
	b		LREF(loop)
	sh1addl		op1,res,res
	nop
	nop
LSYM(3)
	sh1addl		op1,op1,tmp	; 3x
	b		LREF(loop)
	addl		tmp,res,res
	nop
LSYM(4)
	b		LREF(loop)
	sh2addl		op1,res,res
	nop
	nop
LSYM(5)
	sh2addl		op1,op1,tmp	; 5x
	b		LREF(loop)
	addl		tmp,res,res
	nop
LSYM(6)
	sh1addl		op1,op1,tmp	; 3x
	b		LREF(loop)
	sh1addl		tmp,res,res
	nop
LSYM(7)
	zdep		op1,28,29,tmp	; 8x
	sub		tmp,op1,tmp	; 7x
	b		LREF(loop)
	addl		tmp,res,res
LSYM(8)
	b		LREF(loop)
	sh3addl		op1,res,res
	nop
	nop
LSYM(9)
	sh3addl		op1,op1,tmp	; 9x
	b		LREF(loop)
	addl		tmp,res,res
	nop
LSYM(10)
	sh2addl		op1,op1,tmp	; 5x
	b		LREF(loop)
	sh1addl		tmp,res,res
	nop
LSYM(11)
	sh2addl		op1,op1,tmp	; 5x
	sh1addl		tmp,op1,tmp	; 11x
	b		LREF(loop)
	addl		tmp,res,res
LSYM(12)
	sh1addl		op1,op1,tmp	; 3x
	b		LREF(loop)
	sh2addl		tmp,res,res
	nop
LSYM(13)
	sh1addl		op1,op1,tmp	; 3x
	sh2addl		tmp,op1,tmp	; 13x
	b		LREF(loop)
	addl		tmp,res,res
LSYM(14)
	zdep		op1,28,29,tmp	; 8x
	sub		tmp,op1,tmp	; 7x
	b		LREF(loop)
	sh1addl		tmp,res,res
LSYM(15)
	zdep		op1,27,28,tmp	; 16x
	sub		tmp,op1,tmp	; 15x
	b		LREF(loop)
	addl		tmp,res,res
LSYM(16)
	zdep		op1,27,28,tmp	; 16x
	b		LREF(loop)
	addl		tmp,res,res
	nop
LSYM(17)
	zdep		op1,27,28,tmp	; 16x
	addl		tmp,op1,tmp	; 17x
	b		LREF(loop)
	addl		tmp,res,res
LSYM(18)
	sh3addl		op1,op1,tmp	; 9x
	b		LREF(loop)
	sh1addl		tmp,res,res
	nop
LSYM(19)
	sh3addl		op1,op1,tmp	; 9x
	sh1addl		tmp,op1,tmp	; 19x
	b		LREF(loop)
	addl		tmp,res,res
LSYM(20)
	sh2addl		op1,op1,tmp	; 5x
	b		LREF(loop)
	sh2addl		tmp,res,res
	nop
LSYM(21)
	sh2addl		op1,op1,tmp	; 5x
	sh2addl		tmp,op1,tmp	; 21x
	b		LREF(loop)
	addl		tmp,res,res
LSYM(22)
	sh2addl		op1,op1,tmp	; 5x
	sh1addl		tmp,op1,tmp	; 11x
	b		LREF(loop)
	sh1addl		tmp,res,res
LSYM(23)
	sh1addl		op1,op1,tmp	; 3x
	sh3addl		tmp,res,res	; += 8x3
	b		LREF(loop)
	sub		res,op1,res	; -= x
LSYM(24)
	sh1addl		op1,op1,tmp	; 3x
	b		LREF(loop)
	sh3addl		tmp,res,res	; += 8x3
	nop
LSYM(25)
	sh2addl		op1,op1,tmp	; 5x
	sh2addl		tmp,tmp,tmp	; 25x
	b		LREF(loop)
	addl		tmp,res,res
LSYM(26)
	sh1addl		op1,op1,tmp	; 3x
	sh2addl		tmp,op1,tmp	; 13x
	b		LREF(loop)
	sh1addl		tmp,res,res	; += 2x13
LSYM(27)
	sh1addl		op1,op1,tmp	; 3x
	sh3addl		tmp,tmp,tmp	; 27x
	b		LREF(loop)
	addl		tmp,res,res
LSYM(28)
	zdep		op1,28,29,tmp	; 8x
	sub		tmp,op1,tmp	; 7x
	b		LREF(loop)
	sh2addl		tmp,res,res	; += 4x7
LSYM(29)
	sh1addl		op1,op1,tmp	; 3x
	sub		res,tmp,res	; -= 3x
	b		LREF(foo)
	zdep		op1,26,27,tmp	; 32x
LSYM(30)
	zdep		op1,27,28,tmp	; 16x
	sub		tmp,op1,tmp	; 15x
	b		LREF(loop)
	sh1addl		tmp,res,res	; += 2x15
LSYM(31)
	zdep		op1,26,27,tmp	; 32x
	sub		tmp,op1,tmp	; 31x
LSYM(foo)
	b		LREF(loop)
	addl		tmp,res,res
	.exit
	.procend
#endif


Signed Multiply

	destination = source1 (signed *) source2
Возможные формы:
MULS	Multiply Signed			XX * XX -> XXXX



Знаково умножает два операнда и помещает результат в destination, который имеет размер в 2 раза больше чем каждый из операндов.


MULHS	Multiply High Unsigned		XX * XX -> HIGH(XXXX) = XX



Беззнаково умножает операнды и возвращает старшую часть результата. смотри замечания к предидущей команде. При полном умножении (MULS) или при MULHS переполнение не может возникнуть, поэтому OF=0 ------------------------------------------------------------------------------- o Signed Integer Multiply x86 IMUL 8 AccR ( 8x8 -> 16) 8 RR RI ( 8x8 -> 8) 8 RRR RRI ( 8x8 -> 8) 16 AccR (16x16 -> 32) 16 RR RI (16x16 -> 16) 16 RRR RRI (16x16 -> 16) 32 AccR (32x32 -> 64) 32 RR RI (32x32 -> 32) 32 RRR RRI (32x32 -> 32) ------------------------------------------ Alpha MULL 32 RRR RRI (32x32 -> 64) MULQ 64 RRR RRI (64x64 -> 128) ------------------------------------------ PPC MULLHW 32 RRR (32x32 -> 64) (high) MULL 32 RRR (32x32 -> 64) (low) MULLHD 64 RRR (64x64 -> 128) (high) MULLD 64 RRR (64x64 -> 128) (low) ------------------------------------------ MIPS MULT 32 AccR (32x32 -> 64) (HI,LO) DMULT 64 AccR (64x64 -> 128) (HI,LO) ------------------------------------------ SPARC SMUL 32 RRR RRI ------------------------------------------ 68K MULS 16 RR (D-regs) (16x16 -> 32) 32 RR (32x32 -> 32) ?? ---------------------------------------- z80 (*) Complex sequence ---------------------------------------- HPPA ??? ---------------------------------------- VAX-11 ??? ---------------------------------------- JVM IMUL 32 LMUL 64 ---------------------------------------- ARM MULcc 32 RRR (32x32 -> 32) SMULLcc 32 RRRR (32x32 -> 32:32) ----------------------------------------- SH4 MULS.W RR (16x16 -> 32) DMULS.L RR (32x32 -> 64)


Unsigned Division

Беззнаковое деление (и остаток)
	destination = source1 (unsigned /) source2
CISC процессоры как правило используют форму которая сразу дает частное и остаток от деления.

А бывает divide дает только частное

а остаток от деления реализуется другой командой (или вообще нету команды для остатка).

Практически все используют форму XXXX / XX -> XX Часто делимое должно быть помещено в специальные регистры (x86: EDX:EAX, MIPS: HI:LO) Часто при делении вместе с частным вычисляется и остаток. То есть и частное и остаток получается в результате выполнения одной команды. Не у всех процессоров есть деление - например у Alpha его нет. HPPA имет команду которая выполняет шаг деления, Для выполнения деления делается обвязка которая нужное число раз в зависимости от признаков повторяет эту команду. При переполнении после деления: - Деление на 0 - Результат не уместился в регистр может возникать Trap Division by zero. PPC Remainder вычисляеться как:
	# 64-bit signed
		divd	RT,RA,RB	# RT = quotient
		mulld	RT,RT,RB	# RT = quotient * divisor
		subf	RT,RT,RA	# RT = remainder
------------------------------------------------------------------------------ o Unsigned Integer Division x86 DIV 8 AccR (16/8 -> 8) 16 AccR (32/16 -> 16) 32 AccR (64/32 -> 32) ------------------------------------------- Alpha (*) Complex code - not core implemented ------------------------------------------- PPC DIVWU 32 RRR (32/32 -> 32) DIVDU 64 RRR (64/64 -> 64) ------------------------------------------- MIPS DIVU 32 AccR (HI,LO) DDIVU 64 AccR (HI,LO) ------------------------------------------- SPARC UDIV 32 RRR RRI UDIVX 64 RRR RRI V9 ------------------------------------------- 68K DIVU 16 RR (D-regs) (32/16 -> 16) DIVUL 32 RR (64/32 -> 32) ------------------------------------------- z80 (*) Complex sequence ------------------------------------------- HPPA DSc 32 RRR (Divide Step!!) (*) Divide is more complex ------------------------------------------- VAX-11 DIVB2 8 RR DIVB3 8 RRR DIVW2 16 RR DIVW3 16 RRR DIVL2 32 RR DIVL3 32 RRR -------------------------------------------- MCS51 DIV 8 AB (A,B <- A/B) -------------------------------------------- SH4 (*) complex sequence of DIV1/DIV0U


HP-PA Divide


#ifdef L_divU
#define dividend %r26
#define divisor %r25
#define tmp %r1
#define quotient %r29
#define ret %r31

SPACE
GSYM($$divU)
	.proc
	.callinfo	frame=0,no_calls
	.entry
	comb,<		divisor,0,LREF(largedivisor)
        sub		%r0,divisor,%r1		; clear cy as side-effect
	ds		%r0,%r1,%r0
	addc		dividend,dividend,dividend
	ds		%r0,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,dividend
	ds		%r1,divisor,%r1
	addc		dividend,dividend,quotient
	ds		%r1,divisor,%r1
	bv		%r0(ret)
	addc		quotient,quotient,quotient
LSYM(largedivisor)
	comclr,<<	dividend,divisor,quotient
	ldi		1,quotient
	bv,n		%r0(ret)
	.exit
	.procend
#endif


Signed Divison

Деление знаковое (и остаток)
	destination = source1 (signed /) source2


смотри замечания к Unigned Division



------------------------------------------------------------------------------ o Signed Integer Division x86 IDIV 8 AccR (16/8 -> 8) 16 AccR (32/16 -> 16) 32 AccR (64/32 -> 32) ------------------------------------------- Alpha (*) Complex code - not core implemented ------------------------------------------- PPC DIVW 32 RRR (32/32 -> 32) DIVD 64 RRR (64/64 -> 64) ------------------------------------------- MIPS DIV 32 AccR (HI,LO) DDIV 64 AccR (HI,LO) ------------------------------------------- SPARC SDIV 32 RRR RRI SDIVX 64 RRR RRI V9 ------------------------------------------- 68K DIVS 16 RR (D-regs) (32/16 -> 16) ?? DIVSL 32 RR (64/32 -> 32) ------------------------------------------- z80 (*) Complex sequence ------------------------------------------- HPPA (*) Complex sequence ------------------------------------------- VAX-11 ??? ------------------------------------------- JVM IDIV 32 IREM 32 (Remainder) LDIV 64 LREM 64 (Remainder) -------------------------------------------- SH4 (*) complex sequence of DIV1/DIV0S


Increment by 1



	destination = destination + 1
Часто используемая последовательность - например в циклах. В CISC процессорах реализуется как одна команда (Может модифицировать не все арифметические флаги) В RISC процессорах как: add destination, destination, immediate(1) Например SPARC:
	inc	%r5	=>	add	%r5,1,%r5
	inccc	%r5	=>	addcc	%r5,1,%r5
------------------------------------------------------------------------------ o Increment by 1 x86 INC 8 R 16 R 32 R -------------------------------------------- Alpha (*) ADDL/ADDQ 32/64 RRI with 1 -------------------------------------------- PPC (*) ADDI 32/64 RRI with 1 -------------------------------------------- MIPS (*) ADDI/DADDI 32/64 RRI with 1 -------------------------------------------- 68K (*) ADD/ADDA 8/16/32 RI with 1 -------------------------------------------- SPARC (*) ADD max RRI with 1 -------------------------------------------- z80 INC 8 R 16 R -------------------------------------------- HPPA (*) ADDIc 32 RR,I5 with 1 -------------------------------------------- VAX-11 INCB 8 R INCW 16 R INCL 32 R -------------------------------------------- MCS51 INC 8 A R DPTR (memory pointer register) M -------------------------------------------- SH4 (*) ADD RI


Decrement by 1



	destination = destination - 1
Часто используемая последовательность - например в циклах. В CISC процессорах реализуется как одна команда (Может модифицировать не все арифметические флаги) В RISC процессорах как: sub destination, destination, immediate(1) Например SPARC:
	dec	%r5	=>	sub	%r5,1,%r5
	deccc	%r5	=>	subcc	%r5,1,%r5
---------------------------------------------------------------------------- o Decrement by 1 x86 DEC 8 R 16 R 32 R -------------------------------------------- Alpha (*) SUBL/SUBQ 32/64 RRI with 1 -------------------------------------------- PPC (*) SUBF 32/64 RRI with 1 -------------------------------------------- MIPS (*) ADDI/DADDI 32/64 RRI with 1 -------------------------------------------- SPARC (*) SUB max RRI with 1 -------------------------------------------- 68K (*) ADD/ADDA 8/16/32 RI with 1 -------------------------------------------- z80 DEC 8 R 16 R -------------------------------------------- HPPA (*) SUBIc 32 RR,I5 with 1 -------------------------------------------- VAX-11 DECB 8 R DECW 16 R DECL 32 R -------------------------------------------- MCS51 DEC 8 A R M DPTR (memory pointer register) -------------------------------------------- SH4 (*) complex sequence


Negate



	destination = - source
В CISC процессорах реализуется как отдельная команда В RISC процессорах как последовательность sub destination, R0, source (R0 - регистр, который всегда содержит в себе 0) Например SPARC:
	neg	%r5	  =>	sub	%g0,%r5,%r5
	neg	%r5,%r6	  =>	sub	%g0,%r5,%r6
---------------------------------------------------------------------------- o Negate x86 DEC 8 R 16 R 32 R -------------------------------------------- Alpha (*) SUBL/SUBQ 32/64 RRI 0 - value -------------------------------------------- PPC (*) SUBF 32/64 RRI 0 - value (!!) 601: NEG instruction -------------------------------------------- MIPS (*) ADDI/DADDI 32/64 RRI 0 - value -------------------------------------------- SPARC (*) SUB max RRR %g register -------------------------------------------- 68K NEG 8 R (A-,D- regs) 16 R 32 R -------------------------------------------- z80 NEG 8 A --------------------------------------------- HPPA ??? --------------------------------------------- VAX-11 MNEGB 8 RR (R = -R) MNEGW 16 RR MNEGL 32 RR ---------------------------------------------- JVM INEG 32 LNEG 64 ---------------------------------------------- ARM (*) Complex RSB from zero immediate ---------------------------------------------- SH4 NEG RR -----------------------------------------------------------------------------

Index Prev Next