Renesas SH Instruction Set Summary (original) (raw)
Data Transfer Instructions
SH1 SH2 SH3 SH4 SH4A SH2A
mov Rm,Rn
Rm -> Rn
0110nnnnmmmm0011
MT MT
1 1 1 1 1 1
1 1 1 0 1 0
Description
Transfers the source operand to the destination.
Operation
void MOV (int m, int n) { R[n] = R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
mov #imm,Rn
imm -> sign extension -> Rn
1110nnnniiiiiiii
EX MT
1 1 1 1 1 1
1 1 1 1 1 1
Description
Stores immediate data, sign-extended to longword, in general register Rn.
Operation
void MOVI (int i, int n) { if ((i & 0x80) == 0) R[n] = (0x000000FF & i); else R[n] = (0xFFFFFF00 | i);
PC += 2; }
SH2A
movi20 #imm20,Rn
imm -> sign extension -> Rn
0000nnnniiii0000 iiiiiiiiiiiiiiii
1
1
Description
Stores immediate data that has been sign-extended to longword in general register Rn.
Operation
void MOVI20 (int i, int n) { if (i & 0x00080000) == 0) R[n] = (0x000FFFFF & (long)i); else R[n] = (0xFFF00000 | (long)i);
PC += 4; }
SH2A
movi20s #imm20,Rn
imm << 8 -> sign extension -> Rn
0000nnnniiii0001 iiiiiiiiiiiiiiii
1
1
Description
Shifts immediate data 8 bits to the left and performs sign extension to longword, then stores the resulting data in general register Rn. Using an OR or ADD instruction as the next instruction enables a 28-bit absolute address to be generated.
Operation
void MOVI20S (int i, int n) { if (i & 0x00080000) == 0) R[n] = (0x000FFFFF & (long)i); else R[n] = (0xFFF00000 | (long)i);
R[n] <<= 8; PC += 4; }
SH1 SH2 SH3 SH4 SH4A SH2A
mova @(disp,PC),R0
(disp*4) + (PC & 0xFFFFFFFC) + 4 -> R0
11000111dddddddd
EX LS
1 1 1 1 1 1
1 1 1 1 1 1
Description
Stores the effective address of the source operand into general register R0. The 8-bit displacement is zero-extended and quadrupled. Consequently, the relative interval from the operand is PC + 1020 bytes. The PC is the address four bytes after this instruction, but the lowest two bits of the PC are fixed at 00.
Note
SH1*, SH2*, SH3*:
If this instruction is placed immediately after a delayed branch instruction, the PC must point to an address specified by (the starting address of the branch destination) + 2.
SH4*:
If this instruction is executed in a delay slot, a slot illegal instruction exception will be generated.
Operation
void MOVA (int d) { unsigned int disp; disp = (unsigned int)(0x000000FF & d); R[0] = (PC & 0xFFFFFFFC) + 4 + (disp << 2); PC += 2; }
Possible Exceptions
- Slot illegal instruction
SH1 SH2 SH3 SH4 SH4A SH2A
mov.w @(disp,PC),Rn
(disp*2 + PC + 4) -> sign extension -> Rn
1001nnnndddddddd
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Stores immediate data, sign-extended to longword, in general register Rn. The data is stored from memory address (PC + 4 + displacement * 2). The 8-bit displacement is multiplied by two after zero-extension, and so the relative distance from the table is in the range up to PC + 4 + 510 bytes. The PC value is the address of this instruction.
Note
If the following instruction is a branch instruction, it is identified as a slot illegal instruction.
Operation
void MOVWI (int d, int n) { unsigned int disp = (0x000000FF & d); R[n] = Read_16 (PC + 4 + (disp << 1)); if ((R[n] & 0x8000) == 0) R[n] &= 0x0000FFFF; else R[n] |= 0xFFFF0000;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Slot illegal instruction exception
- Data TLB miss exception
- Data TLB protection violation exception
SH1 SH2 SH3 SH4 SH4A SH2A
mov.l @(disp,PC),Rn
(disp*4 + (PC & 0xFFFFFFFC) + 4) -> sign extension -> Rn
1101nnnndddddddd
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Stores immediate data, sign-extended to longword, in general register Rn. The data is stored from memory address (PC + 4 + displacement * 4). The 8-bit displacement is multiplied by four after zero-extension, and so the relative distance from the operand is in the range up to PC + 4 + 1020 bytes. The PC value is the address of this instruction. A value with the lower 2 bits adjusted to 00 is used in address calculation.
Note
If the following instruction is a branch instruction, it is identified as a slot illegal instruction.
Operation
void MOVLI (int d, int n) { unsigned int disp = (0x000000FF & d); R[n] = Read_32 ((PC & 0xFFFFFFFC) + 4 + (disp << 2)); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Slot illegal instruction exception
- Data TLB miss exception
- Data TLB protection violation exception
SH1 SH2 SH3 SH4 SH4A SH2A
mov.b @Rm,Rn
(Rm) -> sign extension -> Rn
0110nnnnmmmm0000
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Transfers the source operand to the destination. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVBL (int m, int n) { R[n] = Read_8 (R[m]); if ((R[n] & 0x80) == 0) R[n] &= 0x000000FF; else R[n] |= 0xFFFFFF00;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.w @Rm,Rn
(Rm) -> sign extension -> Rn
0110nnnnmmmm0001
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Transfers the source operand to the destination. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVWL (int m, int n) { R[n] = Read_16 (R[m]); if ((R[n] & 0x8000) == 0) R[n] &= 0x0000FFFF; else R[n] |= 0xFFFF0000;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.l @Rm,Rn
(Rm) -> Rn
0110nnnnmmmm0010
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Transfers the source operand to the destination.
Operation
void MOVLL (int m, int n) { R[n] = Read_32 (R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.b Rm,@Rn
Rm -> (Rn)
0010nnnnmmmm0000
LS LS
1 1 1 1 1 1
1 1 1 1 1 0
Description
Transfers the source operand to the destination.
Operation
void MOVBS (int m, int n) { Write_8 (R[n], R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH1 SH2 SH3 SH4 SH4A SH2A
mov.w Rm,@Rn
Rm -> (Rn)
0010nnnnmmmm0001
LS LS
1 1 1 1 1 1
1 1 1 1 1 0
Description
Transfers the source operand to the destination.
Operation
void MOVWS (int m, int n) { Write_16 (R[n], R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH1 SH2 SH3 SH4 SH4A SH2A
mov.l Rm,@Rn
Rm -> (Rn)
0010nnnnmmmm0010
LS LS
1 1 1 1 1 1
1 1 1 1 1 0
Description
Transfers the source operand to the destination.
Operation
void MOVLS (int m, int n) { Write_32 (R[n], R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH1 SH2 SH3 SH4 SH4A SH2A
mov.b @Rm+,Rn
(Rm) -> sign extension -> Rn, Rm+1 -> Rm
0110nnnnmmmm0100
LS LS
1 1 1 1 1 1
1 1 1 1/2 1 2
Description
Transfers the source operand to the destination. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVBP (int m, int n) { R[n] = Read_8 (R[m]); if ((R[n] & 0x80) == 0) R[n] &= 0x000000FF; else R[n] |= 0xFFFFFF00;
if (n != m) R[m] += 1;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.w @Rm+,Rn
(Rm) -> sign extension -> Rn, Rm+2 -> Rm
0110nnnnmmmm0101
LS LS
1 1 1 1 1 1
1 1 1 1/2 1 2
Description
Transfers the source operand to the destination. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVWP (int m, int n) { R[n] = Read_16 (R[m]); if ((R[n] & 0x8000) == 0) R[n] &= 0x0000FFFF; else R[n] |= 0xFFFF0000;
if (n != m) R[m] += 2;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.l @Rm+,Rn
(Rm) -> Rn, Rm+4 -> Rm
0110nnnnmmmm0110
LS LS
1 1 1 1 1 1
1 1 1 1/2 1 2
Description
Transfers the source operand to the destination.
Operation
void MOVLP (int m, int n) { R[n] = Read_32 (R[m]);
if (n != m) R[m] += 4;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.b Rm,@-Rn
Rn-1 -> Rn, Rm -> (Rn)
0010nnnnmmmm0100
LS LS
1 1 1 1 1 1
1 1 1 1/1 1 1
Description
Transfers the source operand to the destination.
Operation
void MOVBM (int m, int n) { Write_8 (R[n] - 1, R[m]); R[n] -= 1; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH1 SH2 SH3 SH4 SH4A SH2A
mov.w Rm,@-Rn
Rn-2 -> Rn, Rm -> (Rn)
0010nnnnmmmm0101
LS LS
1 1 1 1 1 1
1 1 1 1/1 1 1
Description
Transfers the source operand to the destination.
Operation
void MOVWM (int m, int n) { Write_16 (R[n] - 2, R[m]); R[n] -= 2; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH1 SH2 SH3 SH4 SH4A SH2A
mov.l Rm,@-Rn
Rn-4 -> Rn, Rm -> (Rn)
0010nnnnmmmm0110
LS LS
1 1 1 1 1 1
1 1 1 1/1 1 1
Description
Transfers the source operand to the destination.
Operation
void MOVLM (int m, int n) { Write_32 (R[n] - 4, R[m]); R[n] -= 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH2A
mov.b @-Rm,R0
Rm-1 -> Rm, (Rm) -> sign extension -> R0
0100mmmm11001011
1
2
Description
Transfers the source operand to the destination. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVRSBM (int m) { R[m] -= 1; R[0] = Read_16 (R[m]);
if ((R[0] & 0x80) == 0) R[0] &= 0x000000FF; else R[0] |= 0xFFFFFF00;
PC+=2; }
Possible Exceptions
- Data address error
SH2A
mov.w @-Rm,R0
Rm-2 -> Rm, (Rm) -> sign extension -> R0
0100mmmm11011011
1
2
Description
Transfers the source operand to the destination. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVRSWM (int m) { R[m]-= 2; R[0] = Read_16 (R[m]);
if ((R[0] & 0x8000) == 0) R[0] &= 0x0000FFFF; else R[0] |= 0xFFFF0000;
PC += 2; }
Possible Exceptions
- Data address error
SH2A
mov.l @-Rm,R0
Rm-4 -> Rm, (Rm) -> R0
0100mmmm11101011
1
2
Description
Transfers the source operand to the destination.
Operation
void MOVRSLM (int m) { R[m] -= 4; R[0] = Read_32 (R[m]); PC += 2; }
Possible Exceptions
- Data address error
SH2A
mov.b R0,@Rn+
R0 -> (Rn), Rn+1 -> Rn
0100nnnn10001011
1
1
Description
Transfers the source operand to the destination.
Operation
void MOVRSBP (int n) { Write_8 (R[n], R[0]); R[n] += 1; PC += 2; }
Possible Exceptions
- Data address error
SH2A
mov.w R0,@Rn+
R0 -> (Rn), Rn+2 -> Rn
0100nnnn10011011
1
1
Description
Transfers the source operand to the destination.
Operation
void MOVRSWP (int n) { Write_16 (R[n], R[0]); R[n] += 2; PC += 2; }
Possible Exceptions
- Data address error
SH2A
mov.l R0,@Rn+
R0 -> (Rn), Rn+4 -> Rn
0100nnnn10101011
1
1
Description
Transfers the source operand to the destination.
Operation
void MOVRSLP (int n) { Write_32 (R[n], R[0]); R[n] += 4; PC += 2; }
Possible Exceptions
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.b @(disp,Rm),R0
(disp + Rm) -> sign extension -> R0
10000100mmmmdddd
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Transfers the source operand to the destination. The 4-bit displacement is only zero-extended, so a range up to +15 bytes can be specified. If a memory operand cannot be reached, the @(R0,Rn) mode can be used instead. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVBL4 (int m, int d) { long disp = (0x0000000F & (long)d); R[0] = Read_8 (R[m] + disp);
if ((R[0] & 0x80) == 0) R[0] &= 0x000000FF; else R[0] |= 0xFFFFFF00;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH2A
mov.b @(disp12,Rm),Rn
(disp + Rm) -> sign extension -> Rn
0011nnnnmmmm0001 0100dddddddddddd
1
2
Description
Transfers the source operand to the destination. This instruction is ideal for data access in a structure or the stack. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVBL12 (int d, int m, int n) { long disp = (0x00000FFF & (long)d); R[n] = Read_8 (R[m] + disp);
if ((R[n] & 0x80) == 0) R[n] &= 0x000000FF; else R[n] |= 0xFFFFFF00;
PC += 4; }
Possible Exceptions
- Data address error
SH2A
movu.b @(disp12,Rm),Rn
(disp + Rm) -> zero extension -> Rn
0011nnnnmmmm0001 1000dddddddddddd
1
2
Description
Transfers a source operand to a destination, performing unsigned data transfer. This instruction is ideal for data access in a structure or the stack. The loaded data is zero-extended to 32 bit before being stored in the destination register.
Operation
void MOVBUL12 (int d, int m, int n) { long disp = (0x00000FFF & (long)d); R[n] = Read_8 (R[m] + disp); R[n] &= 0x000000FF; PC += 4; }
SH1 SH2 SH3 SH4 SH4A SH2A
mov.w @(disp,Rm),R0
(disp*2 + Rm) -> sign extension -> R0
10000101mmmmdddd
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Transfers the source operand to the destination. The 4-bit displacement is multiplied by two after zero-extension, enabling a range up to +30 bytes to be specified. If a memory operand cannot be reached, the @(R0,Rn) mode can be used instead. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVWL4 (int m, int d) { long disp = (0x0000000F & (long)d); R[0] = Read_16 (R[m] + (disp << 1));
if ((R[0] & 0x8000) == 0) R[0] &= 0x0000FFFF; else R[0] |= 0xFFFF0000;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH2A
mov.w @(disp12,Rm),Rn
(disp*2 + Rm) -> sign extension -> Rn
0011nnnnmmmm0001 0101dddddddddddd
1
2
Description
Transfers the source operand to the destination. This instruction is ideal for data access in a structure or the stack. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVWL12 (int d, int m, int n) { long disp = (0x00000FFF & (long)d); R[n] = Read_16 (R[m] + (disp << 1));
if ((R[n] & 0x8000) == 0) R[n] &= 0x0000FFFF; else R[n] |= 0xFFFF0000;
PC += 4; }
Possible Exceptions
- Data address error
SH2A
movu.w @(disp12,Rm),Rn
(disp*2 + Rm) -> zero extension -> Rn
0011nnnnmmmm0001 1001dddddddddddd
1
2
Description
Transfers a source operand to a destination, performing unsigned data transfer. This instruction is ideal for data access in a structure or the stack. The loaded data is zero-extended to 32 bit before being stored in the destination register.
Operation
void MOVWUL12 (int d, int m, int n) { long disp = (0x00000FFF & (long)d); R[n] = Read_16 (R[m] + (disp << 1)); R[n] &= 0x0000FFFF; PC += 4; }
SH1 SH2 SH3 SH4 SH4A SH2A
mov.l @(disp,Rm),Rn
(disp*4 + Rm) -> Rn
0101nnnnmmmmdddd
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Transfers the source operand to the destination. The 4-bit displacement is multiplied by four after zero-extension, enabling a range up to +60 bytes to be specified. If a memory operand cannot be reached, the @(R0,Rn) mode can be used instead.
Operation
void MOVLL4 (int m, int d, int n) { long disp = (0x0000000F & (long)d); R[n] = Read_32 (R[m] + (disp << 2)); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH2A
mov.l @(disp12,Rm),Rn
(disp*4 + Rm) -> Rn
0011nnnnmmmm0001 0110dddddddddddd
1
2
Description
Transfers the source operand to the destination. This instruction is ideal for data access in a structure or the stack.
Operation
void MOVLL12 (int d, int m, int n) { long disp = (0x00000FFF & (long)d); R[n] = Read_32 (R[m] + (disp << 2)); PC += 4; }
Possible Exceptions
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.b R0,@(disp,Rn)
R0 -> (disp + Rn)
10000000nnnndddd
LS LS
1 1 1 1 1 1
1 1 1 1 1 0
Description
Transfers the source operand to the destination. The 4-bit displacement is only zero-extended, so a range up to +15 bytes can be specified. If a memory operand cannot be reached, the @(R0,Rn) mode can be used instead.
Operation
void MOVBS4 (int d, int n) { long disp = (0x0000000F & (long)d); Write_8 (R[n] + disp, R[0]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH2A
mov.b Rm,@(disp12,Rn)
Rm -> (disp + Rn)
0011nnnnmmmm0001 0000dddddddddddd
1
0
Description
Transfers the source operand to the destination. This instruction is ideal for data access in a structure or the stack.
Operation
void MOVBS12 (int d, int m, int n) { long disp = (0x00000FFF & (long)d); Write_8 (R[n] + disp, R[m]); PC += 4; }
Possible Exceptions
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.w R0,@(disp,Rn)
R0 -> (disp*2 + Rn)
10000001nnnndddd
LS LS
1 1 1 1 1 1
1 1 1 1 1 0
Description
Transfers the source operand to the destination. The 4-bit displacement is multiplied by two after zero-extension, enabling a range up to +30 bytes to be specified. If a memory operand cannot be reached, the @(R0,Rn) mode can be used instead.
Operation
void MOVWS4 (int d, int n) { long disp = (0x0000000F & (long)d); Write_16 (R[n] + (disp << 1), R[0]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH2A
mov.w Rm,@(disp12,Rn)
Rm -> (disp*2 + Rn)
0011nnnnmmmm0001 0001dddddddddddd
1
0
Description
Transfers the source operand to the destination. This instruction is ideal for data access in a structure or the stack.
Operation
void MOVWS12 (int d, int m, int n) { long disp = (0x00000FFF & (long)d); Write_16 (R[n] + (disp << 1), R[m]); PC += 4; }
Possible Exceptions
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.l Rm,@(disp,Rn)
Rm -> (disp*4 + Rn)
0001nnnnmmmmdddd
LS LS
1 1 1 1 1 1
1 1 1 1 1 0
Description
Transfers the source operand to the destination. The 4-bit displacement is multiplied by four after zero-extension, enabling a range up to +60 bytes to be specified. If a memory operand cannot be reached, the @(R0,Rn) mode can be used instead.
Operation
void MOVLS4 (int m, int d, int n) { long disp = (0x0000000F & (long)d); Write_32 (R[n] + (disp << 2), R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH2A
mov.l Rm,@(disp12,Rn)
Rm -> (disp*4 + Rn)
0011nnnnmmmm0001 0010dddddddddddd
1
0
Description
Transfers the source operand to the destination. This instruction is ideal for data access in a structure or the stack.
Operation
void MOVLS12 (int d, int m, int n) { long disp = (0x00000FFF & (long)d); Write_32 (R[n] + (disp << 2), R[m]); PC += 4; }
Possible Exceptions
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.b @(R0,Rm),Rn
(R0 + Rm) -> sign extension -> Rn
0000nnnnmmmm1100
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Transfers the source operand to the destination. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVBL0 (int m, int n) { R[n] = Read_8 (R[m] + R[0]);
if ((R[n] & 0x80) == 0) R[n] &= 0x000000FF; else R[n] |= 0xFFFFFF00;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.w @(R0,Rm),Rn
(R0 + Rm) -> sign extension -> Rn
0000nnnnmmmm1101
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Transfers the source operand to the destination. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVWL0 (int m, int n) { R[n] = Read_16 (R[m] + R[0]);
if ((R[n] & 0x8000) == 0) R[n] &= 0x0000FFFF; else R[n] |= 0xFFFF0000;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.l @(R0,Rm),Rn
(R0 + Rm) -> Rn
0000nnnnmmmm1110
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Transfers the source operand to the destination.
Operation
void MOVLL0 (int m, int n) { R[n] = Read_32 (R[m] + R[0]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.b Rm,@(R0,Rn)
Rm -> (R0 + Rn)
0000nnnnmmmm0100
LS LS
1 1 1 1 1 1
1 1 1 1 1 0
Description
Transfers the source operand to the destination.
Operation
void MOVBS0 (int m, int n) { Write_8 (R[n] + R[0], R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH1 SH2 SH3 SH4 SH4A SH2A
mov.w Rm,@(R0,Rn)
Rm -> (R0 + Rn)
0000nnnnmmmm0101
LS LS
1 1 1 1 1 1
1 1 1 1 1 0
Description
Transfers the source operand to the destination.
Operation
void MOVWS0 (int m, int n) { Write_16 (R[n] + R[0], R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH1 SH2 SH3 SH4 SH4A SH2A
mov.l Rm,@(R0,Rn)
Rm -> (R0 + Rn)
0000nnnnmmmm0110
LS LS
1 1 1 1 1 1
1 1 1 1 1 0
Description
Transfers the source operand to the destination.
Operation
void MOVLS0 (int m, int n) { Write_32 (R[n] + R[0], R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH1 SH2 SH3 SH4 SH4A SH2A
mov.b @(disp,GBR),R0
(disp + GBR) -> sign extension -> R0
11000100dddddddd
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Transfers the source operand to the destination. The 8-bit displacement is only zero-extended, so a range up to +255 bytes can be specified. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVBLG (int d) { unsigned int disp = (0x000000FF & d); R[0] = Read_8 (GBR + disp);
if ((R[0] & 0x80) == 0) R[0] &= 0x000000FF; else R[0] |= 0xFFFFFF00;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.w @(disp,GBR),R0
(disp*2 + GBR) -> sign extension -> R0
11000101dddddddd
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Transfers the source operand to the destination. The 8-bit displacement is multiplied by two after zero-extension, enabling a range up to +510 bytes to be specified. The loaded data is sign-extended to 32 bit before being stored in the destination register.
Operation
void MOVWLG (int d) { unsigned int disp = (0x000000FF & d); R[0] = Read_16 (GBR + (disp << 1));
if ((R[0] & 0x8000) == 0) R[0] &= 0x0000FFFF; else R[0] |= 0xFFFF0000;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.l @(disp,GBR),R0
(disp*4 + GBR) -> R0
11000110dddddddd
LS LS
1 1 1 1 1 1
1 1 1 2 1 2
Description
Transfers the source operand to the destination. The 8-bit displacement is multiplied by four after zero-extension, enabling a range up to +1020 bytes to be specified.
Operation
void MOVLLG (int d) { unsigned int disp = (0x000000FF & d); R[0] = Read_32 (GBR + (disp << 2)); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mov.b R0,@(disp,GBR)
R0 -> (disp + GBR)
11000000dddddddd
LS LS
1 1 1 1 1 1
1 1 1 1 1 0
Description
Transfers the source operand to the destination. The 8-bit displacement is only zero-extended, so a range up to +255 bytes can be specified.
Operation
void MOVBSG (int d) { unsigned int disp = (0x000000FF & d); Write_8 (GBR + disp, R[0]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH1 SH2 SH3 SH4 SH4A SH2A
mov.w R0,@(disp,GBR)
R0 -> (disp*2 + GBR)
11000001dddddddd
LS LS
1 1 1 1 1 1
1 1 1 1 1 0
Description
Transfers the source operand to the destination. The 8-bit displacement is multiplied by two after zero-extension, enabling a range up to +510 bytes to be specified.
Operation
void MOVWSG (int d) { unsigned int disp = (0x000000FF & d); Write_16 (GBR + (disp << 1), R[0]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH1 SH2 SH3 SH4 SH4A SH2A
mov.l R0,@(disp,GBR)
R0 -> (disp*4 + GBR)
11000010dddddddd
LS LS
1 1 1 1 1 1
1 1 1 1 1 0
Description
Transfers the source operand to the destination. The 8-bit displacement is multiplied by four after zero-extension, enabling a range up to +1020 bytes to be specified.
Operation
void MOVLSG (int d) { unsigned int disp = (0x000000FF & (long)d); Write_32 (GBR + (disp << 2), R[0]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH4A
movco.l R0,@Rn
LDST -> T If (T == 1): R0 -> Rn 0 -> LDST
0000nnnn01110011
LDST
CO
1
1
Description
MOVCO is used in combination with MOVLI to realize an atomic read-modify-write operation in a single processor.
This instruction copies the value of the LDST flag to the T bit. When the T bit is set to 1, the value of R0 is stored at the address in Rm. If the T bit is cleared to 0, the value is not stored at the address in Rm. Finally, the LDST flag is cleared to 0. Since the LDST flag is cleared by an instruction or exception, storage by the MOVCO instruction only proceeds when no interrupt or exception has occurred between the execution of the MOVLI and MOVCO instructions.
Operation
void MOVCO (int n) { T = LDST; if (T == 1) Write_32 (R[n], R[0]);
LDST = 0; PC += 2 }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
SH4A
movli.l @Rm,R0
1 -> LDST (Rm) -> R0 When interrupt/exception occured: 0 -> LDST
0000mmmm01100011
CO
1
1
Description
MOVLI is used in combination with MOVCO to realize an atomic read-modify-write operation in a single processor.
This instruction sets the LDST flag to 1 and reads the four bytes of data indicated by Rm into R0. If, however, an interrupt or exception occurs, LDST is cleared to 0. Storage by the MOVCO instruction only proceeds when the instruction is executed after the LDST bit has been set by the MOVLI instruction and not cleared by an interrupt or other exception. When LDST has been cleared to 0, the MOVCO instruction clears the T bit and does not proceed with storage.
Operation
void MOVLINK (int m) { LDST = 1; R[0] = Read_32 (R[m]); PC += 2 }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH4A
movua.l @Rm,R0
(Rm) -> R0 Load non-boundary alignment data
0100mmmm10101001
LS
2
2
Description
Loads the longword of data from the effective address indicated by the contents of Rm in memory to R0. The address is not restricted to longword boundaries address (4n). This instruction allows loading from non-longword-boundary addresses (4n + 1, 4n + 2, and 4n + 3). Data address error exceptions do not occur when access is to non-longword-boundary addresses (4n + 1, 4n + 2, and 4n + 3).
Operation
void MOVUAL (int m) { Read_Unaligned_32 (R0, R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error (when the privileged area is accessed from user mode)
SH4A
movua.l @Rm+,R0
(Rm) -> R0, Rm + 4 -> Rm Load non-boundary alignment data
0100mmmm11101001
LS
2
2
Description
Loads the longword of data from the effective address indicated by the contents of Rm in memory to R0. The address is not restricted to longword boundaries address (4n). This instruction allows loading from non-longword-boundary addresses (4n + 1, 4n + 2, and 4n + 3). Data address error exceptions do not occur when access is to non-longword-boundary addresses (4n + 1, 4n + 2, and 4n + 3).
Operation
void MOVUALP (int m) { Read_Unaligned_32 (R0,R[m]);
if (m != 0) R[m] += 4;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error (when the privileged area is accessed from user mode)
SH2A
movml.l Rm,@-R15
R15-4 -> R15, Rm -> (R15) R15-4 -> R15, Rm-1 -> (R15) ... ... R15 - 4 -> R15, R0 -> (R15) Note: When Rm = R15, read Rm as PR
0100mmmm11110001
1-16
1-16
Description
Transfers a source operand to a destination. This instruction performs transfer between a number of general registers (R0 to Rn/Rm) not exceeding the specified register number and memory with the contents of R15 as its address.
If R15 is specified, PR is transferred instead of R15. That is, when nnnn(mmmm) = 1111 is specified, R0 to R14 and PR are the general registers subject to transfer.
Operation
void MOVLMML (int m) { for (int i = m; i >= 0; i--) { if (i == 15) Write_32 (R[15] - 4, PR); else Write_32 (R[15] - 4, R[i]);
R[15] -= 4;
}
PC += 2; }
Possible Exceptions
- Data address error
SH2A
movml.l @R15+,Rn
(R15) -> R0, R15+4 -> R15 (R15) -> R1, R15+4 -> R15 ... ... (R15) -> Rn Note: When Rn = R15, read Rn as PR
0100nnnn11110101
1-16
2-17
Description
Transfers a source operand to a destination. This instruction performs transfer between a number of general registers (R0 to Rn/Rm) not exceeding the specified register number and memory with the contents of R15 as its address.
If R15 is specified, PR is transferred instead of R15. That is, when nnnn(mmmm) = 1111 is specified, R0 to R14 and PR are the general registers subject to transfer.
Operation
void MOVLPML (int n) { for (int i = 0; i <= n; i++) { if (i == 15) PR = Read_32 (R[15]); else R[i] = Read_32 (R[15]);
R[15] += 4;
}
PC += 2; }
Possible Exceptions
- Data address error
SH2A
movmu.l Rm,@-R15
R15-4 -> R15, PR -> (R15) R15-4 -> R15, R14 -> (R15) ... ... R15-4 -> R15, Rm -> (R15) Note: When Rm = R15, read Rm as PR
0100mmmm11110000
1-16
1-16
Description
Transfers a source operand to a destination. This instruction performs transfer between a number of general registers (Rn/Rm to R14, PR) not lower than the specified register number and memory with the contents of R15 as its address.
If R15 is specified, PR is transferred instead of R15.
Operation
void MOVLMMU (int m) { Write_32 (R[15] - 4, PR); R[15] -= 4;
for (int i = 14; i >= m; i--) { Write_32 (R[15] - 4, R[i]); R[15] -= 4; }
PC += 2; }
Possible Exceptions
- Data address error
SH2A
movmu.l @R15+,Rn
(R15) -> Rn, R15+4 -> R15 (R15) -> Rn+1, R15+4 -> R15 ... ... (R15) -> R14, R15+4 -> R15 (R15) -> PR Note: When Rn = R15, read Rn as PR
0100nnnn11110100
1-16
2-17
Description
Transfers a source operand to a destination. This instruction performs transfer between a number of general registers (Rn/Rm to R14, PR) not lower than the specified register number and memory with the contents of R15 as its address.
If R15 is specified, PR is transferred instead of R15.
Operation
void MOVLPMU (int n) { for (int i = n; i <= 14; i++) { R[i] = Read_32 (R[15]); R[15] += 4; }
PR = Read_32 (R[15]); R[15] += 4; PC += 2; }
Possible Exceptions
- Data address error
SH2A
movrt Rn
~T -> Rn
0000nnnn00111001
1
1
Description
Reverses the T bit and then stores the resulting value in general register Rn. The value of Rn is 0 when T = 1 and 1 when T = 0.
Operation
void MOVRT (int n) { if (T == 1) R[n] = 0x00000000; else R[n] = 0x00000001;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
movt Rn
T -> Rn
0000nnnn00101001
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Stores the T bit in general register Rn. The value of Rn is 1 when T = 1 and 0 when T = 0.
Operation
void MOVT (int n) { if (T == 1) R[n] = 0x00000001; else R[n] = 0x00000000; PC += 2; }
SH2A
nott
~T -> T
0000000001101000
~T
1
1
Description
Inverts the T bit, then stores the resulting value in the T bit.
Operation
void NOTT (void) { if (T == 1) T = 0; else T = 1;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
swap.b Rm,Rn
Rm -> swap lower 2 bytes -> Rn
0110nnnnmmmm1000
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Swaps the upper and lower parts of the contents of general register Rm and stores the result in Rn. The 8 bits from bit 15 to bit 8 of Rm are swapped with the 8 bits from bit 7 to bit 0. The upper 16 bits of Rm are transferred directly to the upper 16 bits of Rn.
Operation
void SWAPB (int m, int n) { unsigned long temp0, temp1; temp0 = R[m] & 0xFFFF0000; temp1 = (R[m] & 0x000000FF) << 8; R[n] = (R[m] & 0x0000FF00) >> 8; R[n] = R[n] | temp1 | temp0; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
swap.w Rm,Rn
Rm -> swap upper/lower words -> Rn
0110nnnnmmmm1001
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Swaps the upper and lower parts of the contents of general register Rm and stores the result in Rn. The 16 bits from bit 31 to bit 16 of Rm are swapped with the 16 bits from bit 15 to bit 0.
Operation
void SWAPW (int m, int n) { unsigned long temp; temp = (R[m] >> 16) & 0x0000FFFF; R[n] = R[m] << 16; R[n] |= temp; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
xtrct Rm,Rn
Rm:Rn middle 32 bits -> Rn
0010nnnnmmmm1101
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Extracts the middle 32 bits from the 64-bit contents of linked general registers Rm and Rn, and stores the result in Rn.
Operation
void XTRCT (int m, int n) { unsigned long high = (R[m] << 16) & 0xFFFF0000; unsigned long low = (R[n] >> 16) & 0x0000FFFF; R[n] = high | low; PC += 2; }
Bit Manipulation Instructions
SH2A
band.b #imm3,@disp12,Rn
(imm of (disp+Rn)) & T -> T
0011nnnn0iii1001 0100dddddddddddd
Result
3
3
Description
ANDs a specified bit in memory at the address indicated by (disp + Rn) with the T bit, and stores the result in the T bit. The bit number is specified by 3-bit immediate data. With this instruction, data is read from memory as a byte unit.
Operation
void BANDM (int d, int i, int n) { long disp = (0x00000FFF & (long)d); long imm = (0x00000007 & (long)i); long temp = Read_8 (R[n] + disp); long assignbit = (0x00000001 << imm) & temp;
if ((T == 0) || (assignbit == 0)) T = 0; else T = 1;
PC += 4; }
Possible Exceptions
- Data address error
SH2A
bandnot.b #imm3,@(disp12,Rn)
~(imm of (disp+Rn)) & T -> T
0011nnnn0iii1001 1100dddddddddddd
Result
3
3
Description
ANDs the value obtained by inverting a specified bit of memory at the address indicated by (disp + Rn) with the T bit, and stores the result in the T bit. The bit number is specified by 3-bit immediate data. With this instruction, data is read from memory as a byte unit.
Operation
void BANDNOTM (int d, int i, int n) { long disp = (0x00000FFF & (long)d); long imm = (0x00000007 & (long)i); long temp = Read_8 (R[n] + disp); long assignbit = (0x00000001 << imm) & temp;
if ((T == 1) && (assignbit == 0)) T = 1; else T = 0;
PC += 4; }
Possible Exceptions
- Data address error
SH2A
bclr.b #imm3,@(disp12,Rn)
0 -> (imm of (disp+Rn))
0011nnnn0iii1001 0000dddddddddddd
3
2
Description
Clears a specified bit of memory at the address indicated by (disp + Rn). The bit number is specified by 3-bit immediate data. After data is read from memory as a byte unit, clearing of the specified bit is executed and the resulting data is then written to memory as a byte unit.
Operation
void BCLRM (int d, int i, int n) { long disp = (0x00000FFF & (long)d); long imm = (0x00000007 & (long)i); long temp = Read_8 (R[n] + disp); temp &= (~(0x00000001 < <imm)); write_8="" (r[n]="" +="" disp,="" temp);="" pc="" }="" <="" p=""></imm));>
Possible Exceptions
- Data address error
SH2A
bclr #imm3,Rn
0 -> imm of Rn
10000110nnnn0iii
1
1
Description
Clears a specified bit of the LSB 8 bits of a general register Rn. The bit number is specified by 3-bit immediate data.
Operation
void CLR (int i, int n) { long imm, temp; imm = (0x00000007 & (long)i); R[n] &= (~(0x00000001 << imm)); PC += 2; }
SH2A
bld.b #imm3,@(disp12,Rn)
(imm of (disp+Rn)) -> T
0011nnnn0iii1001 0011dddddddddddd
Result
3
3
Description
Stores a specified bit of memory at the address indicated by (disp + Rn) in the T bit. The bit number is specified by 3-bit immediate data. Data is read from memory as a byte unit.
Operation
void BLDM (int d, int i, int n) { long disp = (0x00000FFF & (long)d); long imm = (0x00000007 & (long)i); long temp = Read_8 (R[n] + disp); long assignbit = (0x00000001 << imm) & temp;
if (assignbit == 0) T = 0; else T = 1;
PC += 4; }
Possible Exceptions
- Data address error
SH2A
bld #imm3,Rn
imm of Rn -> T
10000111nnnn1iii
Result
1
1
Description
Stores a specified bit of the LSB 8 bits of a general register Rn in the T bit. The bit number is specified by 3-bit immediate data.
Operation
void BLD (int i, int n) { long imm, assignbit; imm = (0x00000007 & (long)i); assignbit = (0x00000001 << imm) & R[n];
if (assignbit == 0) T = 0; else T = 1;
PC += 2; }
SH2A
bldnot.b #imm3,@(disp12,Rn)
~(imm of (disp+Rn)) -> T
0011nnnn0iii1001 1011dddddddddddd
Result
3
3
Description
Inverts a specified bit of memory at the address indicated by (disp + Rn), and stores the resulting value in the T bit. The bit number is specified by 3-bit immediate data. Data is read from memory as a byte unit.
Operation
void BLDNOTM (int d, int i, int n) { long disp = (0x00000FFF & (long)d); long imm = (0x00000007 & (long)i); long temp = Read_8 (R[n] + disp); long assignbit = (0x00000001 << imm) & temp;
if (assignbit == 0) T = 1; else T = 0;
PC += 4; }
Possible Exceptions
- Data address error
SH2A
bor.b #imm3,@(disp12,Rn)
(imm of (disp+Rn)) | T -> T
0011nnnn0iii1001 0101dddddddddddd
Result
3
3
Description
ORs a specified bit in memory at the address indicated by (disp + Rn) with the T bit, and stores the result in the T bit. The bit number is specified by 3-bit immediate data. Data is read from memory as a byte unit.
Operation
void BORM (int d, int i, int n) { long disp = (0x00000FFF & (long)d); long imm = (0x00000007 & (long)i); long temp = Read_8 (R[n] + disp); long assignbit = (0x00000001 << imm) & temp;
if ((T == 0) && (assignbit == 0)) T = 0; else T = 1;
PC += 4; }
Possible Exceptions
- Data address error
SH2A
bornot.b #imm3,@(disp12,Rn)
~(imm of (disp+Rn)) | T -> T
0011nnnn0iii1001 1101dddddddddddd
Result
3
3
Description
ORs the value obtained by inverting a specified bit of memory at the address indicated by (disp + Rn) with the T bit, and stores the result in the T bit. The bit number is specified by 3-bit immediate data. With this instruction, data is read from memory as a byte unit.
Operation
void BORNOTM (int d, int i, int n) { long disp = (0x00000FFF & (long)d); long imm = (0x00000007 & (long)i); long temp = Read_8 (R[n] + disp); long assignbit = (0x00000001 << imm) & temp;
if ((T == 1) || (assignbit == 0)) T = 1; else T = 0;
PC += 4; }
Possible Exceptions
- Data address error
SH2A
bset.b #imm3,@(disp12,Rn)
1 -> (imm of (disp+Rn))
0011nnnn0iii1001 0001dddddddddddd
3
2
Description
Sets to 1 a specified bit of memory at the address indicated by (disp + Rn). The bit number is specified by 3-bit immediate data. After data is read from memory as a byte unit, the specified bit is set to 1, and the resulting data is then written to memory as a byte unit.
Operation
void BSETM (int d, int i, int n) { long disp = (0x00000FFF & (long)d); long imm = (0x00000007 & (long)i); long temp = Read_8 (R[n] + disp); temp |= (0x00000001 << imm); Write_8 (R[n] + disp, temp); PC += 4; }
Possible Exceptions
- Data address error
SH2A
bset #imm3,Rn
1 -> imm of Rn
10000110nnnn1iii
1
1
Description
Sets to 1 a specified bit of the LSB 8 bits of a general register Rn. The bit number is specified by 3-bit immediate data.
Operation
void BSET (int i, int n) { long imm, temp; imm = (0x00000007 & (long)i); R[n] |= (0x00000001 << imm); PC += 2; }
SH2A
bst.b #imm3,@(disp12,Rn)
T -> (imm of (disp+Rn))
0011nnnn0iii1001 0010dddddddddddd
3
2
Description
Transfers the contents of the T bit to a specified 1-bit location of memory at the address indicated by (disp + Rn). The bit number is specified by 3-bit immediate data. After data is read from memory as a byte unit, transfer from the T bit to the specified bit is executed, and the resulting data is then written to memory as a byte unit.
Operation
void BSTM (int d, int i, int n) { long disp = (0x00000FFF & (long)d); long imm = (0x00000007 & (long)i); long temp = Read_8 (R[n] + disp);
if (T == 0) temp &= (~(0x00000001 << imm)); else temp |= (0x00000001 << imm);
Write_8 (R[n] + disp, temp); PC += 4; }
Possible Exceptions
- Data address error
SH2A
bst #imm3,Rn
T -> imm of Rn
10000111nnnn0iii
1
1
Description
Transfers the contents of the T bit to a specified 1-bit location of the LSB 8 bits of a general register Rn. The bit number is specified by 3-bit immediate data.
Operation
void BST (int i, int n) { long disp, imm; disp = (0x00000FFF & (long)d); imm = (0x00000007 & (long)i);
if (T == 0) R[n] &= (~(0x00000001 << imm)); else R[n] |= (0x00000001 << imm);
PC += 2; }
SH2A
bxor.b #imm3,@(disp12,Rn)
(imm of (disp+Rn)) ^ T -> T
0011nnnn0iii1001 0110dddddddddddd
Result
3
3
Description
Exclusive-ORs a specified bit in memory at the address indicated by (disp + Rn) with the T bit, and stores the result in the T bit. The bit number is specified by 3-bit immediate data. With this instruction, data is read from memory as a byte unit.
Operation
void BXORM (int d, int i, int n) { long disp = (0x00000FFF & (long)d); long imm = (0x00000007 & (long)i); long temp = Read_8 (R[n] + disp); long assignbit = (0x00000001 << imm) & temp;
if (assignbit == 0) { if (T == 0) T = 0; else T = 1; } else { if (T == 0) T = 1; else T = 0; }
PC += 4; }
Possible Exceptions
- Data address error
Arithmetic Operation Instructions
SH1 SH2 SH3 SH4 SH4A SH2A
add Rm,Rn
Rn + Rm -> Rn
0011nnnnmmmm1100
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Adds together the contents of general registers Rn and Rm and stores the result in Rn.
Operation
void ADD (int m, int n) { R[n] += R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
add #imm,Rn
Rn + (sign extension)imm
0111nnnniiiiiiii
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Adds together the contents of general register Rn and the immediate value and stores the result in Rn. The 8-bit immediate value is sign-extended to 32 bits, which allows it to be used for immediate subtraction or decrement operations.
Operation
void ADDI (int i, int n) { if ((i & 0x80) == 0) R[n] += (0x000000FF & (long)i); else R[n] += (0xFFFFFF00 | (long)i);
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
addc Rm,Rn
Rn + Rm + T -> Rn, carry -> T
0011nnnnmmmm1110
Carry
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Adds together the contents of general registers Rn and Rm and the T bit, and stores the result in Rn. A carry resulting from the operation is reflected in the T bit. This instruction can be used to implement additions exceeding 32 bits.
Operation
void ADDC (int m, int n) { unsigned long tmp0, tmp1; tmp1 = R[n] + R[m]; tmp0 = R[n]; R[n] = tmp1 + T;
if (tmp0>tmp1) T = 1; else T = 0;
if (tmp1 > R[n]) T = 1;
PC += 2; }
Example
clrt ! r0:r1 (64 bits) + r2:r3 (64 bits) = r0:r1 (64 bits) addc r3,r1 ! Before execution T = 0, r1 = 0x00000001, r3 = 0xFFFFFFFF ! After execution T = 1, r1 = 0x00000000 addc r2,r0 ! Before execution T = 1, r0 = 0x00000000, r2 = 0x00000000 ! After execution T = 0, r0 = 0x00000001
SH1 SH2 SH3 SH4 SH4A SH2A
addv Rm,Rn
Rn + Rm -> Rn, overflow -> T
0011nnnnmmmm1111
Overflow
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Adds together the contents of general registers Rn and Rm and stores the result in Rn. If overflow occurs, the T bit is set.
Operation
void ADDV (int m, int n) { long dest, src, ans;
if ((long)R[n] >= 0) dest = 0; else dest = 1;
if ((long)R[m] >= 0) src = 0; else src = 1;
src += dest; R[n] += R[m];
if ((long)R[n] >= 0) ans = 0; else ans = 1;
ans += dest;
if (src == 0 || src == 2) { if (ans == 1) T = 1; else T = 0; } else T = 0;
PC += 2; }
Example
addv r0,r1 ! Before execution: r0 = 0x00000001, r1 = 0x7FFFFFFE, T = 0 ! After execution: r1 = 0x7FFFFFFF, T = 0
addv r0,r1 ! Before execution: r0 = 0x00000002, r1 = 0x7FFFFFFE, T = 0 ! After execution: r1 = 0x80000000, T = 1
SH1 SH2 SH3 SH4 SH4A SH2A
cmp/eq #imm,R0
If R0 = (sign extension)imm: 1 -> T Else: 0 -> T
10001000iiiiiiii
Result
MT EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Compares general register R0 and the sign-extended 8-bit immediate data and sets the T bit if the values are equal. If they are not equal the T bit is cleared. The contents of R0 are not changed.
Operation
void CMPIM (int i) { long imm;
if ((i & 0x80) == 0) imm = (0x000000FF & (long i)); else imm = (0xFFFFFF00 | (long i));
if (R[0] == imm) T = 1; else T = 0;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
cmp/eq Rm,Rn
If Rn = Rm: 1 -> T Else: 0 -> T
0011nnnnmmmm0000
Result
MT EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Compares general registers Rn and Rm, and sets the T bit if they are equal. The contents of Rn and Rm are not changed.
Operation
void CMPEQ (int m, int n) { if (R[n] == R[m]) T = 1; else T = 0;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
cmp/hs Rm,Rn
If Rn >= Rm (unsigned): 1 -> T Else: 0 -> T
0011nnnnmmmm0010
Result
MT EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Compares general registers Rn and Rm, and sets the T bit if Rn is greater or equal Rm. The values for the comparison are interpreted as unsigned integer values. The contents of Rn and Rm are not changed.
Operation
void CMPHI (int m, int n) { if ((unsigned long)R[n] >= (unsigned long)R[m]) T = 1; else T = 0;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
cmp/ge Rm,Rn
If Rn >= Rm (signed): 1 -> T Else: 0 -> T
0011nnnnmmmm0011
Result
MT EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Compares general registers Rn and Rm, and sets the T bit if Rn is greater or equal Rm. The values for the comparison are interpreted as signed integer values. The contents of Rn and Rm are not changed.
Operation
void CMPGE (int m, int n) { if ((long)R[n] >= (long)R[m]) T = 1; else T = 0;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
cmp/hi Rm,Rn
If Rn > Rm (unsigned): 1 -> T Else: 0 -> T
0011nnnnmmmm0110
Result
MT EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Compares general registers Rn and Rm, and sets the T bit if Rn is greater Rm. The values for the comparison are interpreted as unsigned integer values. The contents of Rn and Rm are not changed.
Operation
void CMPHI (int m, int n) { if ((unsigned long)R[n] > (unsigned long)R[m]) T = 1; else T = 0;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
cmp/gt Rm,Rn
If Rn > Rm (signed): 1 -> T Else: 0 -> T
0011nnnnmmmm0111
Result
MT EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Compares general registers Rn and Rm, and sets the T bit if Rn is greater Rm. The values for the comparison are interpreted as signed integer values. The contents of Rn and Rm are not changed.
Operation
void CMPGT (int m, int n) { if ((long)R[n] > (long)R[m]) T = 1; else T = 0;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
cmp/pl Rn
If Rn > 0 (signed): 1 -> T Else: 0 -> T
0100nnnn00010101
Result
MT EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Compares general register Rn and sets the T bit if Rn is greater 0. The value in Rn for the comparison is interpreted as signed integer. The contents of Rn are not changed.
Operation
void CMPPL (int n) { if ((long)R[n] > 0) T = 1; else T = 0;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
cmp/pz Rn
If Rn >= 0 (signed): 1 -> T Else: 0 -> T
0100nnnn00010001
Result
MT EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Compares general register Rn and sets the T bit if Rn is greater or equal 0. The value in Rn for the comparison is interpreted as signed integer. The contents of Rn are not changed.
Operation
void CMPPZ (int n) { if ((long)R[n] >= 0) T = 1; else T = 0;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
cmp/str Rm,Rn
If Rn and Rm have an equal byte: 1 -> T Else: 0 -> T
0010nnnnmmmm1100
Result
MT EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Compares general registers Rn and Rm, and sets the T bit if any of the 4 bytes in Rn are equal to the corresponding byte in Rm. The contents of Rn and Rm are not changed.
Note
This instruction can be used to speed up some string operations such as finding the string length of a zero terminated string or string matching.
Operation
void CMPSTR (int m, int n) { unsigned long temp; long HH, HL, LH, LL; temp = R[n] ^ R[m]; HH = (temp & 0xFF000000) >> 24; HL = (temp & 0x00FF0000) >> 16; LH = (temp & 0x0000FF00) >> 8; LL = temp & 0x000000FF; HH = HH && HL && LH && LL;
if (HH == 0) T = 1; else T = 0;
PC += 2; }
Example
cmp/str r2,r3 ! r2 = "ABCD", r3 = "XYCZ" bt target ! T = 1, so branch is taken.
SH2A
clips.b Rn
If Rn > 0x0000007F: 0x0000007F -> Rn, 1 -> CS If Rn < 0xFFFFFF80: 0xFFFFFF80 -> Rn, 1 -> CS
0100nnnn10010001
1
1
Description
Determines saturation. Signed data is used with this instruction. The saturation upper-limit value is stored in general register Rn if the contents of Rn exceed the saturation upper-limit value, or the saturation lower-limit value is stored in Rn if the contents of Rn are less than the saturation lower-limit value, and the CS bit is set to 1. The saturation upper-limit value is 0x0000007F (127). The saturation lower-limit value is 0xFFFFFF80 (-128).
Note
The CS bit value does not change if the contents of general register Rn do not exceed the saturation upper-limit value or are not less than the saturation lower-limit value.
Operation
void CLIPSB (int n) { if (R[n] > 0x0000007F) { R[n] = 0x0000007F; CS = 1; } else if (R[n] < 0xFFFFFF80) { R[n] = 0xFFFFFF80; CS = 1; }
PC += 2; }
SH2A
clips.w Rn
If Rn > 0x00007FFF: 0x00007FFF -> Rn, 1 -> CS If Rn < 0xFFFF8000: 0xFFFF8000 -> Rn, 1 -> CS
0100nnnn10010101
1
1
Description
Determines saturation. Signed data is used with this instruction. The saturation upper-limit value is stored in general register Rn if the contents of Rn exceed the saturation upper-limit value, or the saturation lower-limit value is stored in Rn if the contents of Rn are less than the saturation lower-limit value, and the CS bit is set to 1. The saturation upper-limit value is 0x00007FFF (32767). The saturation lower-limit value is 0xFFFF8000 (-32768).
Note
The CS bit value does not change if the contents of general register Rn do not exceed the saturation upper-limit value or are not less than the saturation lower-limit value.
Operation
void CLIPSW (int n) { if (R[n] > 0x00007FFF) { R[n] = 0x00007FFF; CS = 1; } else if (R[n] < 0xFFFF8000) { R[n] = 0xFFFF8000; CS = 1; }
PC += 2; }
SH2A
clipu.b Rn
If Rn > 0x000000FF: 0x000000FF -> Rn, 1 -> CS
0100nnnn10000001
1
1
Description
Determines saturation. Unsigned data is used with this instruction. If the contents of general register Rn exceed the saturation value, the saturation value is stored in Rn and the CS bit is set to 1. The saturation value is 0x000000FF (255).
Note
The CS bit value does not change if the contents of general register Rn do not exceed the saturation upper-limit value.
Operation
void CLIPUB (int n) { if (R[n] > 0x000000FF) { R[n] = 0x000000FF; CS = 1; }
PC += 2; }
SH2A
clipu.w Rn
If Rn > 0x0000FFFF: 0x0000FFFF -> Rn, 1 -> CS
0100nnnn10000101
1
1
Description
Determines saturation. Unsigned data is used with this instruction. If the contents of general register Rn exceed the saturation value, the saturation value is stored in Rn and the CS bit is set to 1. The saturation value is 0x0000FFFF (65535).
Note
The CS bit value does not change if the contents of general register Rn do not exceed the saturation upper-limit value.
Operation
void CLIPUW (int n) { if (R[n] > 0x0000FFFF) { R[n] = 0x0000FFFF; CS = 1; }
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
div0s Rm,Rn
MSB of Rn -> Q, MSB of Rm -> M, M ^ Q -> T
0010nnnnmmmm0111
Result
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Performs initial settings for signed division. This instruction is followed by a DIV1 instruction that executes 1-digit division, for example, and repeated division steps are executed to find the quotient. See the description of the DIV1 instruction for details.
Note
This instruction can also be used to compare the signs of Rm and Rn. If the signs of Rm and Rn are equal, T will be set to 0. If the signs of Rm and Rn are not equal, T will be set to 1.
Operation
void DIV0S (int m, int n) { if ((R[n] & 0x80000000) == 0) Q = 0; else Q = 1;
if ((R[m] & 0x80000000) == 0) M = 0; else M = 1;
T = ! (M == Q); PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
div0u
0 -> M, 0 -> Q, 0 -> T
0000000000011001
0
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Performs initial settings for unsigned division. This instruction is followed by a DIV1 instruction that executes 1-digit division, for example, and repeated division steps are executed to find the quotient. See the description of the DIV1 instruction for details.
Operation
void DIV0U (void) { M = Q = T = 0; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
div1 Rm,Rn
1-step division (Rn / Rm)
0011nnnnmmmm0100
Result
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Performs 1-digit division (1-step division) of the 32-bit contents of general register Rn (dividend) by the contents of Rm (divisor). The quotient is obtained by repeated execution of this instruction alone or in combination with other instructions. The specified registers and the M, Q, and T bits must not be modified during these repeated executions.
In 1-step division, the dividend is shifted 1 bit to the left, the divisor is subtracted from this, and the quotient bit is reflected in the Q bit according to whether the result is positive or negative.
Detection of division by zero or overflow is not provided. Check for division by zero and overflow division before executing the division. A remainder operation is not provided. Find the remainder by finding the product of the divisor and the obtained quotient, and subtracting this value from the dividend:
remainder = dividend - (divisor * quotient)
Initial settings should first be made with the DIV0S or DIV0U instruction. DIV1 is executed once for each bit of the divisor. If a quotient of more than 17 bits is required, place an ROTCL instruction before the DIV1 instruction. See the examples for details of the division sequence.
Operation
void DIV1 (int m, int n) { unsigned long tmp0, tmp2; unsigned char old_q, tmp1;
old_q = Q; Q = (0x80000000 & R[n]) != 0; tmp2 = R[m]; R[n] <<= 1; R[n] |= (unsigned long)T;
if (old_q == 0) { if (M == 0) { tmp0 = R[n]; R[n] -= tmp2; tmp1 = R[n] > tmp0;
if (Q == 0)
Q = tmp1;
else if (Q == 1)
Q = tmp1 == 0;
}
else if (M == 1)
{
tmp0 = R[n];
R[n] += tmp2;
tmp1 = R[n] < tmp0;
if (Q == 0)
Q = tmp1 == 0;
else if (Q == 1)
Q = tmp1;
}
}
else if (old_q == 1) { if (M == 0) { tmp0 = R[n]; R[n] += tmp2; tmp1 = R[n] < tmp0;
if (Q == 0)
Q = tmp1;
else if (Q == 1)
Q = tmp1 == 0;
}
else if (M == 1)
{
tmp0 = R[n];
R[n] -= tmp2;
tmp1 = R[n] > tmp0;
if (Q == 0)
Q = tmp1 == 0;
else if (Q == 1)
Q = tmp1;
}
}
T = (Q == M); PC += 2; }
Example
! r1 (32 bits) / r0 (16 bits) = r1 (16 bits) (unsigned)
shll16 r0 ! Set divisor in upper 16 bits, clear lower 16 bits to 0
tst r0,r0 ! Check for division by zero bt zero_div
cmp/hs r0,r1 ! Check for overflow bt over_div
div0u ! Flag initialization
.rept 16 div1 r0,r1 ! Repeat 16 times .endr
rotcl r1 extu.w r1,r1 ! r1 = quotient
! r1:r2 (64 bits) / r0 (32 bits) = r2 (32 bits) (unsigned)
tst r0,r0 ! Check for division by zero bt zero_div
cmp/hs r0,r1 ! Check for overflow bt over_div
div0u ! Flag initialization
.rept 32 rotcl r2 ! Repeat 32 times div1 r0,r1 .endr
rotcl r2 ! r2 = quotient
! r1 (16 bits) / r0 (16 bits) = r1 (16 bits) (signed)
shll16 r0 ! Set divisor in upper 16 bits, clear lower 16 bits to 0 exts.w r1,r1 ! Dividend sign-extended to 32 bits mov #0,r2 mov r1,r3 rotcl r3 subc r2,r1 ! If dividend is negative, subtract 1 div0s r0,r1 ! Flag initialization
.rept 16 div1 r0,r1 ! Repeat 16 times .endr
exts.w r1,r1 rotcl r1 ! r1 = quotient (one's complement notation) addc r2,r1 ! If MSB of quotient is 1, add 1 to convert to two's complement notation exts.w r1,r1 ! r1 = quotient (two's complement notation)
! r2 (32 bits) / r0 (32 bits) = r2 (32 bits) (signed)
mov r2,r3 rotcl r3 subc r1,r1 ! Dividend sign-extended to 64 bits (r1:r2) mov #0,r3 subc r3,r2 ! If dividend is negative, subtract 1 to convert to one's complement notation div0s r0,r1 ! Flag initialization
.rept 32 rotcl r2 ! Repeat 32 times div1 r0,r1 .endr
rotcl r2 ! r2 = quotient (one's complement notation) addc r3,r2 ! If MSB of quotient is 1, add 1 to convert to two's complement notation ! r2 = quotient (two's complement notation)
! r4 (8 bits) / r5 (8 bits) = r0 (8 bits) (unsigned)
extu.b r4,r4 ! Optional, not needed if value is known to be zero extended. extu.b r5,r5 ! Optional, not needed if value is known to be zero extended. shll8 r5 div0u
.rept 8 div1 r5,r4 ! Repeat 8 times .endr
rotcl r4 extu.b r4,r0
SH2A
divs R0,Rn
Signed, Rn / R0 -> Rn 32 / 32 -> 32 bits
0100nnnn10010100
36
36
Description
Executes division of the 32-bit contents of a general register Rn (dividend) by the contents of R0 (divisor). This instruction executes signed division and finds the quotient only. A remainder operation is not provided. To obtain the remainder, find the product of the divisor and the obtained quotient, and subtract this value from the dividend. The sign of the remainder will be the same as that of the dividend.
Note
An overflow exception will occur if the negative maximum value (0x00000000) is divided by -1. If division by zero is performed a division by zero exception will occur.
If an interrupt is generated while this instruction is being executed, execution will be halted. The return address will be the start address of this instruction, and this instruction will be re-executed. This avoids increased interrupt latency.
Operation
void DIVS (int n) { R[n] = R[n] / R[0]; PC += 2; }
Possible Exceptions
- Overflow exception
- Division by zero exception
SH2A
divu R0,Rn
Unsigned, Rn / R0 -> Rn 32 / 32 -> 32 bits
0100nnnn10000100
36
36
Description
Executes division of the 32-bit contents of a general register Rn (dividend) by the contents of R0 (divisor). This instruction executes unsigned division and finds the quotient only. A remainder operation is not provided. To obtain the remainder, find the product of the divisor and the obtained quotient, and subtract this value from the dividend.
Note
A division by zero exception will occur if division by zero is performed.
If an interrupt is generated while this instruction is being executed, execution will be halted. The return address will be the start address of this instruction, and this instruction will be re-executed. This avoids increased interrupt latency.
Operation
void DIVU (int n) { R[n]= (unsigned long)R[n] / (unsigned long)R[0]; PC += 2; }
Possible Exceptions
- Division by zero exception
SH2 SH3 SH4 SH4A SH2A
dmuls.l Rm,Rn
Signed, Rn * Rm -> MACH:MACL 32 * 32 -> 64 bits
0011nnnnmmmm1101
CO EX
2 2 2 1 2
2-4 2-5 4/4 2 3
Description
Performs 32-bit multiplication of the contents of general register Rn by the contents of Rm, and stores the 64-bit result in the MACH and MACL registers. The multiplication is performed as a signed arithmetic operation.
Note
On SH4, when MAC*/MUL* is followed by an STS.L MAC*,@-Rn instruction, the latency of MAC*/MUL* is 5 cycles.
Operation
void DMULS (int m, int n) { unsigned long RnL, RnH, RmL, RmH, Res0, Res1, Res2; unsigned long temp0, temp1, temp2, temp3; long tempm, tempn, fnLmL;
tempn = (long)R[n]; tempm = (long)R[m];
if (tempn < 0) tempn = 0 - tempn;
if (tempm < 0) tempm = 0 - tempm;
if ((long)(R[n] ^ R[m]) < 0) fnLmL = -1; else fnLmL = 0;
temp1 = (unsigned long)tempn; temp2 = (unsigned long)tempm;
RnL = temp1 & 0x0000FFFF; RnH = (temp1 >> 16) & 0x0000FFFF;
RmL = temp2 & 0x0000FFFF; RmH = (temp2 >> 16) & 0x0000FFFF;
temp0 = RmL * RnL; temp1 = RmH * RnL; temp2 = RmL * RnH; temp3 = RmH * RnH;
Res2 = 0; Res1 = temp1 + temp2; if (Res1 < temp1) Res2 += 0x00010000;
temp1 = (Res1 << 16) & 0xFFFF0000; Res0 = temp0 + temp1; if (Res0 < temp0) Res2++;
Res2 = Res2 + ((Res1 >> 16) & 0x0000FFFF) + temp3;
if (fnLmL < 0)
{
Res2 = Res2;
if (Res0 == 0)
Res2++;
else
Res0 = (Res0) + 1;
}
MACH = Res2; MACL = Res0; PC += 2; }
SH2 SH3 SH4 SH4A SH2A
dmulu.l Rm,Rn
Unsigned, Rn * Rm -> MACH:MACL 32 * 32 -> 64 bits
0011nnnnmmmm0101
CO EX
2 2 2 1 2
2-4 2-5 4/4 2 2
Description
Performs 32-bit multiplication of the contents of general register Rn by the contents of Rm, and stores the 64-bit result in the MACH and MACL registers. The multiplication is performed as an unsigned arithmetic operation.
Note
On SH4, when MAC*/MUL* is followed by an STS.L MAC*,@-Rn instruction, the latency of MAC*/MUL* is 5 cycles.
Operation
void DMULU (int m, int n) { unsigned long RnL, RnH, RmL, RmH, Res0, Res1, Res2; unsigned long temp0, temp1, temp2, temp3;
RnL = R[n] & 0x0000FFFF; RnH = (R[n] >> 16) & 0x0000FFFF;
RmL = R[m] & 0x0000FFFF; RmH = (R[m] >> 16) & 0x0000FFFF;
temp0 = RmL * RnL; temp1 = RmH * RnL; temp2 = RmL * RnH; temp3 = RmH * RnH;
Res2 = 0 Res1 = temp1 + temp2; if (Res1 < temp1) Res2 += 0x00010000;
temp1 = (Res1 << 16) & 0xFFFF0000; Res0 = temp0 + temp1; if (Res0 < temp0) Res2++;
Res2 = Res2 + ((Res1 >> 16) & 0x0000FFFF) + temp3;
MACH = Res2; MACL = Res0; PC += 2; }
SH2 SH3 SH4 SH4A SH2A
dt Rn
Rn-1 -> Rn If Rn = 0: 1 -> T Else: 0 -> T
0100nnnn00010000
EX EX
1 1 1 1 1
1 1 1 1 1
Description
Decrements the contents of general register Rn by 1 and compares the result with zero. If the result is zero, the T bit is set to 1. If the result is nonzero, the T bit is cleared to 0.
Operation
void DT (int n) { R[n]--;
if (R[n] == 0) T = 1; else T = 0;
PC += 2; }
Example
mov #4,r4 ! Set loop count
loop: add r0,r1 dt r5 ! Decrement r5 value and check for 0. bf loop ! if T = 0 branch to loop ! (in this example, 4 loop iterations are executed)
SH1 SH2 SH3 SH4 SH4A SH2A
exts.b Rm,Rn
Rm sign-extended from byte -> Rn
0110nnnnmmmm1110
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Sign-extends the contents of general register Rm and stores the result in Rn. The value of Rm bit 7 is transferred to Rn bits 8 to 31.
Operation
void EXTSB (int m, int n) { R[n] = R[m];
if ((R[m] & 0x00000080) == 0) R[n] & = 0x000000FF; else R[n] |= 0xFFFFFF00;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
exts.w Rm,Rn
Rm sign-extended from word -> Rn
0110nnnnmmmm1111
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Sign-extends the contents of general register Rm and stores the result in Rn. The value of Rm bit 15 is transferred to Rn bits 16 to 31.
Operation
void EXTSW (int m, int n) { R[n] = R[m];
if ((R[m] & 0x00008000) == 0) R[n] & = 0x0000FFFF; else R[n] |= 0xFFFF0000;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
extu.b Rm,Rn
Rm zero-extended from byte -> Rn
0110nnnnmmmm1100
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Zero-extends the contents of general register Rm and stores the result in Rn. 0 is transferred to Rn bits 8 to 31.
Operation
void EXTUB (int m, int n) { R[n] = R[m]; R[n] &= 0x000000FF; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
extu.w Rm,Rn
Rm zero-extended from word -> Rn
0110nnnnmmmm1101
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Zero-extends the contents of general register Rm and stores the result in Rn. 0 is transferred to Rn bits 16 to 31.
Operation
void EXTUW (int m, int n) { R[n] = R[m]; R[n] &= 0x0000FFFF; PC += 2; }
SH2 SH3 SH4 SH4A SH2A
mac.l @Rm+,@Rn+
Signed, (Rn) * (Rm) + MAC -> MAC 32 * 32 + 64 -> 64 bits
0000nnnnmmmm1111
CO CO
2 2 2 2 4
2-4 2-5 2/4 5 5
Description
Performs signed multiplication of the 32-bit operands whose addresses are the contents of general registers Rm and Rn, adds the 64-bit result to the MAC register contents, and stores the result in the MAC register. Operands Rm and Rn are each incremented by 4 each time they are read.
When the S bit is cleared to 0, the 64-bit result is stored in the coupled MACH and MACL registers.
When bit S is set to 1, addition to the MAC register is a saturation operation of 48 bits starting from the LSB. For the saturation operation, only the lower 48 bits of the MACL register are enabled and the result is limited to a range of 0xFFFF800000000000 (minimum) and 0x00007FFFFFFFFFFF (maximum).
Note
On SH4, when MAC*/MUL* is followed by an STS.L MAC*,@-Rn instruction, the latency of MAC*/MUL* is 5 cycles. In the case of consecutive executions of MAC.W/MAC.L, the latency is decreased to 2 cycles.
Operation
void MACL (int m, int n) { unsigned long RnL, RnH, RmL, RmH, Res0, Res1, Res2; unsigned long temp0, temp1, temp2, temp3; long tempm, tempn, fnLmL;
tempn = Read_32 (R[n]); R[n] += 4; tempm = Read_32 (R[m]); R[m] += 4;
if ((long)(tempn ^ tempm) < 0) fnLmL = -1; else fnLmL = 0;
if (tempn < 0) tempn = 0 - tempn; if (tempm < 0) tempm = 0 - tempm;
temp1 = (unsigned long)tempn; temp2 = (unsigned long)tempm;
RnL = temp1 & 0x0000FFFF; RnH = (temp1 >> 16) & 0x0000FFFF; RmL = temp2 & 0x0000FFFF; RmH = (temp2 >> 16) & 0x0000FFFF; temp0 = RmL * RnL; temp1 = RmH * RnL; temp2 = RmL * RnH; temp3 = RmH * RnH;
Res2 = 0;
Res1 = temp1 + temp2; if (Res1 < temp1) Res2 += 0x00010000;
temp1 = (Res1 << 16) & 0xFFFF0000;
Res0 = temp0 + temp1; if (Res0 < temp0) Res2++;
Res2 = Res2 + ((Res1 >> 16) & 0x0000FFFF) + temp3;
if(fnLmL < 0)
{
Res2 = Res2;
if (Res0 == 0)
Res2++;
else
Res0 = (Res0) + 1;
}
if (S == 1) { Res0 = MACL + Res0; if (MACL > Res0) Res2++;
Res2 += MACH & 0x0000FFFF;
if (((long)Res2 < 0) && (Res2 < 0xFFFF8000))
{
Res2 = 0xFFFF8000;
Res0 = 0x00000000;
}
if (((long)Res2 > 0) && (Res2 > 0x00007FFF))
{
Res2 = 0x00007FFF;
Res0 = 0xFFFFFFFF;
}
MACH = (Res2 & 0x0000FFFF) | (MACH & 0xFFFF0000);
MACL = Res0;
} else { Res0 = MACL + Res0; if (MACL > Res0) Res2 ++;
Res2 += MACH;
MACH = Res2;
MACL = Res0;
}
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
mac.w @Rm+,@Rn+
Signed, (Rn) * (Rm) + MAC -> MAC SH1: 16 * 16 + 42 -> 42 bits Other: 16 * 16 + 64 -> 64 bits
0100nnnnmmmm1111
CO CO
2 2 2 2 2 3
2-3 2-3 2-5 2/4 4 4
Description
Performs signed multiplication of the 16-bit operands whose addresses are the contents of general registers Rm and Rn, adds the 32-bit result to the MAC register contents, and stores the result in the MAC register. Operands Rm and Rn are each incremented by 2 each time they are read.
If the S bit is 0, a 16 * 16 + 64 -> 64-bit multiply-and-accumulate operation is performed, and the 64-bit result is stored in the linked MACH and MACL registers.
If the S bit is 1, a 16 * 16 + 32 -> 32-bit multiply-and-accumulate operation is performed, and the addition to the MAC register contents is a saturation operation. In a saturation operation, only the MACL register is valid, and the result range is limited to 0x80000000 (minimum value) to 0x7FFFFFFF (maximum value). If overflow occurs, the LSB of the MACH register is set to 1. 0x80000000 (minimum value) is stored in the MACL register if the result overflows in the negative direction, and 0x7FFFFFFF (maximum value) is stored if the result overflows in the positive direction
Note
When the S bit is 0, the SH2 and SH-DSP CPU perform a 16 * 16 + 64 -> 64 bit multiply and accumulate operation and the SH1 CPU performs a 16 * 16 + 42 -> 42 bit multiply and accumulate operation.
On SH4, when MAC*/MUL* is followed by an STS.L MAC*,@-Rn instruction, the latency of MAC*/MUL* is 5 cycles. In the case of consecutive executions of MAC.W/MAC.L, the latency is decreased to 2 cycles.
Operation
void MACW (int m, int n) { long tempm, tempn, dest, src, ans; unsigned long templ;
tempn = Read_16 (R[n]); R[n] += 2; tempm = Read_16 (R[m]); R[m] += 2;
templ = MACL; tempm = ((long)(short)tempn * (long)(short)tempm);
if ((long)MACL >= 0) dest = 0; else dest = 1;
if ((long)tempm >= 0) { src = 0; tempn = 0; } else { src = 1; tempn = 0xFFFFFFFF; }
src += dest; MACL += tempm;
if ((long)MACL >= 0) ans = 0; else ans = 1;
ans += dest;
if (S == 1) { if (ans == 1) { #if SH1 if (src == 0 || src == 2) MACH |= 0x00000001; #endif
if (src == 0)
MACL = 0x7FFFFFFF;
if (src == 2)
MACL = 0x80000000;
}
} else { MACH += tempn; if (templ > MACL) MACH += 1;
#if SH1
if ((MACH & 0x00000200) == 0)
MACH &= 0x000003FF;
else
MACH |= 0xFFFFFC00;
#endif
}
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH2 SH3 SH4 SH4A SH2A
mul.l Rm,Rn
Rn * Rm -> MACL 32 * 32 -> 32 bits
0000nnnnmmmm0111
CO EX
2 2 2 1 2
2-4 2-4 4/4 2 3
Description
Performs 32-bit multiplication of the contents of general registers Rn and Rm, and stores the lower 32 bits of the result in the MACL register. The contents of MACH are not changed.
Note
On SH4, when MAC*/MUL* is followed by an STS.L MAC*,@-Rn instruction, the latency of MAC*/MUL* is 5 cycles.
Operation
void MULL (int m, int n) { MACL = R[n] * R[m]; PC += 2; }
SH2A
mulr R0,Rn
R0 * Rn -> Rn 32 * 32 -> 32 bits
0100nnnn10000000
2
4
Description
Performs 32-bit multiplication of the contents of general register R0 by Rn, and stores the lower 32 bits of the result in general register Rn.
Operation
void MULR (int n) { R[n] = R[0] * R[n]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
muls.w Rm,Rn
Signed, Rn * Rm -> MACL 16 * 16 -> 32 bits
0010nnnnmmmm1111
CO EX
2 2 2 2 1 1
1-3 1-3 1-3 4/4 1 2
Description
Performs 16-bit multiplication of the contents of general registers Rn and Rm, and stores the 32-bit result in the MACL register. The multiplication is performed as a signed arithmetic operation. The contents of MACH are not changed.
Note
On SH4, when MAC*/MUL* is followed by an STS.L MAC*,@-Rn instruction, the latency of MAC*/MUL* is 5 cycles.
Operation
void MULS (int m, int n) { MACL = ((long)(short)R[n] * (long)(short)R[m]); PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
mulu.w Rm,Rn
Unsigned, Rn * Rm -> MACL 16 * 16 -> 32 bits
0010nnnnmmmm1110
CO EX
2 2 2 2 1 1
1-3 1-3 1-3 4/4 1 2
Description
Performs 16-bit multiplication of the contents of general registers Rn and Rm, and stores the 32-bit result in the MACL register. The multiplication is performed as an unsigned arithmetic operation. The contents of MACH are not changed.
Note
On SH4, when MAC*/MUL* is followed by an STS.L MAC*,@-Rn instruction, the latency of MAC*/MUL* is 5 cycles.
Operation
void MULU (int m, int n) { MACL = ((unsigned long)(unsigned short)R[n]* (unsigned long)(unsigned short)R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
neg Rm,Rn
0 - Rm -> Rn
0110nnnnmmmm1011
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Finds the two's complement of the contents of general register Rm and stores the result in Rn. That is, it subtracts Rm from 0 and stores the result in Rn.
Operation
void NEG (int m, int n) { R[n] = 0 - R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
negc Rm,Rn
0 - Rm - T -> Rn, borrow -> T
0110nnnnmmmm1010
Borrow
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Subtracts the contents of general register Rm and the T bit from 0 and stores the result in Rn. A borrow resulting from the operation is reflected in the T bit. This instruction can be used for sign inversion of a value exceeding 32 bits.
Note
This instruction can also be used to efficiently store the reversed T bit value in a general register, if the MOVRT instruction is not available.
Operation
void NEGC (int m, int n) { unsigned long temp; temp = 0 - R[m]; R[n] = temp - T;
if (0 < temp) T = 1; else T = 0;
if (temp < R[n]) T = 1;
PC += 2; }
Example
! Sign inversion of r0:r1 (64 bits)
clrt negc r1,r1 ! Before execution: r1 = 0x00000001, T = 0 ! After execution: r1 = 0xFFFFFFFF, T = 1 negc r0,r0 ! Before execution: r0 = 0x00000000, T = 1 ! After execution: r0 = 0xFFFFFFFF, T = 1
! Store reversed T bit in r0
mov #-1,r1 negc r1,r0 ! r0 = 0 - (-1) - T ! r0 = 1 - T ! Notice that T bit will be modified by the negc operation. ! In this case, T will be always set to 1.
SH1 SH2 SH3 SH4 SH4A SH2A
sub Rm,Rn
Rn - Rm -> Rn
0011nnnnmmmm1000
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Subtracts the contents of general register Rm from the contents of general register Rn and stores the result in Rn. For immediate data subtraction, ADD #imm,Rn should be used.
Operation
void SUB (int m, int n) { R[n] -= R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
subc Rm,Rn
Rn - Rm - T -> Rn, borrow -> T
0011nnnnmmmm1010
Borrow
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Subtracts the contents of general register Rm and the T bit from the contents of general register Rn, and stores the result in Rn. A borrow resulting from the operation is reflected in the T bit. This instruction is used for subtractions exceeding 32 bits.
Note
This instruction can also be used to store the T bit to all the bits of a general register.
Operation
void SUBC (int m, int n) { unsigned long tmp0, tmp1; tmp1 = R[n] - R[m]; tmp0 = R[n]; R[n] = tmp1 - T;
if (tmp0 < tmp1) T = 1; else T = 0;
if (tmp1 < R[n]) T = 1;
PC += 2; }
Example
! r0:r1(64 bits) - r2:r3(64 bits) = r0:r1(64 bits)
clrt subc r3,r1 ! Before execution: T = 0, r1 = 0x00000000, r3 = 0x00000001 ! After execution: T = 1, r1 = 0xFFFFFFFF subc r2,r0 ! Before execution: T = 1, r0 = 0x00000000, r2 = 0x00000000 ! After execution: T = 1, r0 = 0xFFFFFFFF
! Store T bit to all bits of r0
subc r0,r0 ! r0 = r0 - r0 - T ! r0 = 0 - T ! Notice that the T bit is modified by the subc operation.
SH1 SH2 SH3 SH4 SH4A SH2A
subv Rm,Rn
Rn - Rm -> Rn, underflow -> T
0011nnnnmmmm1011
Underflow
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Subtracts the contents of general register Rm from the contents of general register Rn, and stores the result in Rn. If underflow occurs, the T bit is set.
Operation
void SUBV (int m, int n) { long dest, src, ans;
if ((long)R[n] >= 0) dest = 0; else dest = 1;
if ((long)R[m] >= 0) src = 0; else src = 1;
src += dest; R[n] -= R[m];
if ((long)R[n] >= 0) ans = 0; else ans = 1;
ans += dest;
if (src == 1) { if (ans == 1) T = 1; else T = 0; } else T = 0;
PC += 2; }
Example
subv r0,r1 ! Before execution: r0 = 0x00000002, r1 = 0x80000001 ! After execution: r1 = 0x7FFFFFFF, T = 1
subv r2,r3 ! Before execution: r2 = 0xFFFFFFFE, r3 = 0x7FFFFFFE ! After execution r3 = 0x80000000, T = 1
Logic Operation Instructions
SH1 SH2 SH3 SH4 SH4A SH2A
and Rm,Rn
Rn & Rm -> Rn
0010nnnnmmmm1001
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
ANDs the contents of general registers Rn and Rm and stores the result in Rn.
Operation
void AND (int m, int n) { R[n] &= R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
and #imm,R0
R0 & (zero extend)imm -> R0
11001001iiiiiiii
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
ANDs the contents of general register R0 and the zero-extended immediate value and stores the result in R0.
Note
Since the 8-bit immediate value is zero-extended, the upper 24 bits of R0 are always cleared to zero.
Operation
void ANDI (int i) { R[0] &= (0x000000FF & (long)i); PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
and.b #imm,@(R0,GBR)
(R0 + GBR) & (zero extend)imm -> (R0 + GBR)
11001101iiiiiiii
CO CO
2 2 2 4 3 3
3 3 3 4 3
Description
ANDs the contents of the memory byte indicated by the indirect GBR address with the immediate value and writes the result back to the memory byte.
Operation
void ANDM (long i) { long temp = Read_8 (GBR + R[0]); temp &= 0x000000FF & (long)i; Write_8 (GBR + R[0], temp); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
Exceptions are checked taking a data access by this instruction as a byte load and a byte store.
SH1 SH2 SH3 SH4 SH4A SH2A
not Rm,Rn
~Rm -> Rn
0110nnnnmmmm0111
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Finds the one's complement of the contents of general register Rm and stores the result in Rn. That is, it inverts the Rm bits and stores the result in Rn.
Operation
void NOT (int m, int n) { R[n] = ~R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
or Rm,Rn
Rn | Rm -> Rn
0010nnnnmmmm1011
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
ORs the contents of general registers Rn and Rm and stores the result in Rn.
Operation
void OR (int m, int n) { R[n] |= R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
or #imm,R0
R0 | (zero extend)imm -> R0
11001011iiiiiiii
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
ORs the contents of general register R0 and the zero-extended immediate value and stores the result in R0.
Note
Since the 8-bit immediate value is zero-extended, the upper 24 bits of R0 are not modified.
Operation
void ORI (int i) { R[0] |= (0x000000FF & (long)i); PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
or.b #imm,@(R0,GBR)
(R0 + GBR) | (zero extend)imm -> (R0 + GBR)
11001111iiiiiiii
CO CO
2 2 2 4 3 3
3 3 3 4 3 2
Description
ORs the contents of the memory byte indicated by the indirect GBR address with the immediate value and writes the result back to the memory byte.
Operation
void ORM (int i) { long temp = Read_8 (GBR + R[0]); temp |= (0x000000FF & (long)i); Write_8 (GBR + R[0], temp); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
Exceptions are checked taking a data access by this instruction as a byte load and a byte store.
SH1 SH2 SH3 SH4 SH4A SH2A
tas.b @Rn
If (Rn) = 0: 1 -> T Else: 0 -> T 1 -> MSB of (Rn)
0100nnnn00011011
Result
CO CO
2 2 2 5 4 3
4 4 3/4 5 4 3
Description
Reads byte data from the address specified by general register Rn, and sets the T bit to 1 if the data is 0, or clears the T bit to 0 if the data is not 0. Then, data bit 7 is set to 1, and the data is written to the address specified by Rn. During this operation, the bus is not released.
On SH4 and SH4A this instruction purges the cache block corresponding to the memory area specified by the contents of general register Rn. The purge operation is executed as follows.
In a purge operation, data is accessed using the contents of general register Rn as the effective address. If there is a cache hit and the corresponding cache block is dirty (U bit = 1), the contents of that cache block are written back to external memory, and the cache block is then invalidated (by clearing the V bit to 0). If there is a cache hit and the corresponding cache block is clean (U bit = 0), the cache block is simply invalidated (by clearing the V bit to 0). A purge is not executed in the event of a cache miss, or if the accessed memory location is non-cacheable.
Note
The two TAS.B memory accesses are executed automatically. Another memory access is not executed between the two TAS.B accesses.
On SH3 the destination of the TAS instruction should be placed in a non-cacheable space when the cache is enabled.
Operation
void TAS (int n) { int temp = Read_8 (R[n]); // Bus Lock
if (temp == 0) T = 1; else T = 0;
temp |= 0x00000080; Write_8 (R[n], temp); // Bus unlock PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
Exceptions are checked taking a data access by this instruction as a byte load and a byte store.
SH1 SH2 SH3 SH4 SH4A SH2A
tst Rm,Rn
If Rn & Rm = 0: 1 -> T Else: 0 -> T
0010nnnnmmmm1000
Result
MT EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
ANDs the contents of general registers Rn and Rm, and sets the T bit if the result is zero. If the result is nonzero, the T bit is cleared. The contents of Rn are not changed.
Operation
void TST (int m, int n) { if ((R[n] & R[m]) == 0) T = 1; else T = 0;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
tst #imm,R0
If R0 & (zero extend)imm = 0: 1 -> T Else: 0 -> T
11001000iiiiiiii
Result
MT EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
ANDs the contents of general register R0 and the zero-extended immediate value and sets the T bit if the result is zero. If the result is nonzero, the T bit is cleared. The contents of Rn are not changed.
Note
Since the 8-bit immediate value is zero-extended, this instruction can only be used to test the lower 8 bits of R0.
Operation
void TSTI (int i) { long temp = R[0] & (0x000000FF & (long)i);
if (temp == 0) T = 1; else T = 0;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
tst.b #imm,@(R0,GBR)
If (R0 + GBR) & (zero extend)imm = 0: 1 -> T Else 0: -> T
11001100iiiiiiii
Result
CO CO
2 2 2 3 3 3
3 3 3 3 3 3
Description
ANDs the contents of the memory byte indicated by the indirect GBR address with the zero-extended immediate value and sets the T bit if the result is zero. If the result is nonzero, the T bit is cleared. The contents of the memory byte are not changed.
Operation
void TSTM (int i) { long temp = Read_8 (GBR + R[0]); temp &= (0x000000FF & (long)i);
if (temp == 0) T = 1; else T = 0;
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
Exceptions are checked taking a data access by this instruction as a byte load and a byte store.
SH1 SH2 SH3 SH4 SH4A SH2A
xor Rm,Rn
Rn ^ Rm -> Rn
0010nnnnmmmm1010
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
XORs the contents of general registers Rn and Rm and stores the result in Rn.
Operation
void XOR (long m, long n) { R[n] ^= R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
xor #imm,R0
R0 ^ (zero extend)imm -> R0
11001010iiiiiiii
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
XORs the contents of general register R0 and the zero-extended immediate value and stores the result in R0.
Note
Since the 8-bit immediate value is zero-extended, the upper 24 bits of R0 are not modified.
Operation
void XORI (int i) { R[0] ^= (0x000000FF & (long)i); PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
xor.b #imm,@(R0,GBR)
(R0 + GBR) ^ (zero extend)imm -> (R0 + GBR)
11001110iiiiiiii
CO CO
2 2 2 4 3 3
3 3 3 4 3 2
Description
XORs the contents of the memory byte indicated by the indirect GBR address with the immediate value and writes the result back to the memory byte.
Operation
void XORM (int i) { int temp = Read_8 (GBR + R[0]); temp ^= (0x000000FF & (long)i); Write_8 (GBR + R[0], temp); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
Exceptions are checked taking a data access by this instruction as a byte load and a byte store.
Shift Instructions
SH1 SH2 SH3 SH4 SH4A SH2A
rotcl Rn
T << Rn << T
0100nnnn00100100
MSB
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Rotates the contents of general register Rn one bit to the left through the T bit, and stores the result in Rn. The bit rotated out of the operand is transferred to the T bit.
Operation
void ROTCL (int n) { long temp;
if ((R[n] & 0x80000000) == 0) temp = 0; else temp = 1;
R[n] <<= 1;
if (T == 1) R[n] |= 0x00000001; else R[n] &= 0xFFFFFFFE;
if (temp == 1) T = 1; else T = 0;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
rotcr Rn
T >> Rn >> T
0100nnnn00100101
LSB
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Rotates the contents of general register Rn one bit to the right through the T bit, and stores the result in Rn. The bit rotated out of the operand is transferred to the T bit.
Operation
void ROTCR (int n) { long temp;
if ((R[n] & 0x00000001) == 0) temp = 0; else temp = 1;
R[n] >>= 1;
if (T == 1) R[n] |= 0x80000000; else R[n] &= 0x7FFFFFFF;
if (temp == 1) T = 1; else T = 0;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
rotl Rn
T << Rn << MSB
0100nnnn00000100
MSB
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Rotates the contents of general register Rn one bit to the left, and stores the result in Rn. The bit rotated out of the operand is transferred to the T bit.
Operation
void ROTL (int n) { if ((R[n] & 0x80000000) == 0) T = 0; else T = 1;
R[n] <<= 1;
if (T == 1) R[n] |= 0x00000001; else R[n] &= 0xFFFFFFFE;
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
rotr Rn
LSB >> Rn >> T
0100nnnn00000101
LSB
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Rotates the contents of general register Rn one bit to the right, and stores the result in Rn. The bit rotated out of the operand is transferred to the T bit.
Operation
void ROTR (int n) { if ((R[n] & 0x00000001) == 0) T = 0; else T = 1;
R[n] >>= 1;
if (T == 1) R[n] |= 0x80000000; else R[n] &= 0x7FFFFFFF;
PC += 2; }
SH3 SH4 SH4A SH2A
shad Rm,Rn
If Rm >= 0: Rn << Rm -> Rn If Rm < 0: Rn >> |Rm| -> [MSB -> Rn]
0100nnnnmmmm1100
EX EX
1 1 1 1
1 1 1 1
Description
Arithmetically shifts the contents of general register Rn. General register Rm specifies the shift direction and the number of bits to be shifted.
Rn register contents are shifted to the left if the Rm register value is positive, and to the right if negative. In a shift to the right, the MSB is added at the upper end.
The number of bits to be shifted is specified by the lower 5 bits (bits 4 to 0) of the Rm register. If the value is negative (MSB = 1), the Rm register is represented as a two's complement. The left shift range is 0 to 31, and the right shift range, 1 to 32.
Note
On SH4, if there is a load of the shift amount immediately before an SHAD/SHLD instruction, the latency of the load is increased by 1 cycle.
Operation
void SHAD (int m, int n) { int sgn = R[m] & 0x80000000;
if (sgn == 0) R[n] <<= (R[m] & 0x1F); else if ((R[m] & 0x1F) == 0) { if ((R[n] & 0x80000000) == 0) R[n] = 0; else R[n] = 0xFFFFFFFF; } else R[n] = (long)R[n] >> ((~R[m] & 0x1F) + 1);
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
shal Rn
T << Rn << 0
0100nnnn00100000
MSB
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Arithmetically shifts the contents of general register Rn one bit to the left and stores the result in Rn. The bit shifted out of the operand is transferred to the T bit.
Operation
void SHAL (int n) { if ((R[n] & 0x80000000) == 0) T = 0; else T = 1;
R[n] <<= 1; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
shar Rn
MSB >> Rn >> T
0100nnnn00100001
LSB
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Arithmetically shifts the contents of general register Rn one bit to the right and stores the result in Rn. The bit shifted out of the operand is transferred to the T bit.
Operation
void SHAR (int n) { long temp;
if ((R[n] & 0x00000001) == 0) T = 0; else T = 1;
if ((R[n] & 0x80000000) == 0) temp = 0; else temp = 1;
R[n] >>= 1;
if (temp == 1) R[n] |= 0x80000000; else R[n] &= 0x7FFFFFFF;
PC += 2; }
SH3 SH4 SH4A SH2A
shld Rm,Rn
If Rm >= 0: Rn << Rm -> Rn If Rm < 0: Rn >> |Rm| -> [0 -> Rn]
0100nnnnmmmm1101
EX EX
1 1 1 1
1 1 1 1
Description
Logically shifts the contents of general register Rn. General register Rm specifies the shift direction and the number of bits to be shifted.
Rn register contents are shifted to the left if the Rm register value is positive, and to the right if negative. In a shift to the right, 0s are added at the upper end.
The number of bits to be shifted is specified by the lower 5 bits (bits 4 to 0) of the Rm register. If the value is negative (MSB = 1), the Rm register is represented as a two's complement. The left shift range is 0 to 31, and the right shift range, 1 to 32.
Note
On SH4, if there is a load of the shift amount immediately before an SHAD/SHLD instruction, the latency of the load is increased by 1 cycle.
Operation
void SHLD (int m, int n) { int sgn = R[m] & 0x80000000;
if (sgn == 0) R[n] <<= (R[m] & 0x1F); else if ((R[m] & 0x1F) == 0) R[n] = 0; else R[n] = (unsigned)R[n] >> ((~R[m] & 0x1F) + 1);
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
shll Rn
T << Rn << 0
0100nnnn00000000
MSB
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Logically shifts the contents of general register Rn one bit to the left and stores the result in Rn. The bit shifted out of the operand is transferred to the T bit.
Note
Effectively, the operation performed is the same as the SHAL instruction.
Operation
void SHLL (int n) { if ((R[n] & 0x80000000) == 0) T = 0; else T = 1;
R[n] <<= 1; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
shll2 Rn
Rn << 2 -> Rn
0100nnnn00001000
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Logically shifts the contents of general register Rn 2 bits to the left and stores the result in Rn. The bits shifted out of the operand are discarded.
Operation
void SHLL2 (int n) { R[n] <<= 2; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
shll8 Rn
Rn << 8 -> Rn
0100nnnn00011000
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Logically shifts the contents of general register Rn 8 bits to the left and stores the result in Rn. The bits shifted out of the operand are discarded.
Operation
void SHLL8 (int n) { R[n] <<= 8; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
shll16 Rn
Rn << 16 -> Rn
0100nnnn00101000
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Logically shifts the contents of general register Rn 16 bits to the left and stores the result in Rn. The bits shifted out of the operand are discarded.
Operation
void SHLL16 (int n) { R[n] <<= 16; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
shlr Rn
0 >> Rn >> T
0100nnnn00000001
LSB
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Logically shifts the contents of general register Rn one bit to the right and stores the result in Rn. The bit shifted out of the operand is transferred to the T bit.
Operation
void SHLR (int n) { if ((R[n] & 0x00000001) == 0) T = 0; else T = 1;
R[n] >>= 1; R[n] &= 0x7FFFFFFF; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
shlr2 Rn
Rn >> 2 -> [0 -> Rn]
0100nnnn00001001
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Logically shifts the contents of general register Rn 2 bits to the right, and stores the result in Rn. The bits shifted out of the operand are discarded.
Operation
void SHLR2 (int n) { R[n] >>= 2; R[n] &= 0x3FFFFFFF; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
shlr8 Rn
Rn >> 8 -> [0 -> Rn]
0100nnnn00011001
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Logically shifts the contents of general register Rn 8 bits to the right, and stores the result in Rn. The bits shifted out of the operand are discarded.
Operation
void SHLR8 (int n) { R[n] >>= 8; R[n] &= 0x00FFFFFF; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
shlr16 Rn
Rn >> 16 -> [0 -> Rn]
0100nnnn00101001
EX EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Logically shifts the contents of general register Rn 16 bits to the right and stores the result in Rn. The bits shifted out of the operand are discarded.
Operation
void SHLR16 (int n) { R[n] >>= 16; R[n] &= 0x0000FFFF; PC += 2; }
Branch Instructions
SH1 SH2 SH3 SH4 SH4A SH2A
bf label
If T = 0: disp*2 + PC + 4 -> PC Else: nop
10001011dddddddd
BR BR
1 1 1 1 1-3 1/3
1/3 1/3 1/3 1/2 1 1/3
Description
This is a conditional branch instruction that references the T bit. The branch is taken if T = 0, and not taken if T = 1. The branch destination is address (PC + 4 + displacement * 2). The PC source value is the BF instruction address. As the 8-bit displacement is multiplied by two after sign-extension, the branch destination can be located in the range from -256 to +254 bytes from the BF instruction.
Note
If the branch destination cannot be reached, the branch must be handled by using BF in combination with a BRA or JMP instruction, for example.
On some SH4 implementations a branch with a displacement value of zero does not cause the pipeline I-stage to be stalled even if the branch is taken. This can be utilized for efficient conditional operations.
On some SH2E implementations (SH7055) there is an FPU related hardware bug which affects this instruction. The recommended workaround is to use bt/s with a nop in the delay slot. See also documents "sh2eoc.pdf" and "win_update_a.pdf".
Operation
void BF (int d) { int disp; if ((d & 0x80) == 0) disp = (0x000000FF & d); else disp = (0xFFFFFF00 | d);
if (T == 0) PC = PC + 4 + (disp << 1); else PC += 2; }
Possible Exceptions
- Slot illegal instruction exception
SH2 SH3 SH4 SH4A SH2A
bf/s label
If T = 0: disp*2 + PC + 4 -> PC Else: nop (Delayed branch)
10001111dddddddd
BR BR
1 1 1 1-3 1/2
1/2 1/2 1/2 1 1/2
Description
This is a delayed conditional branch instruction that references the T bit. If T = 1, the next instruction is executed and the branch is not taken. If T = 0, the branch is taken after execution of the next instruction.
The branch destination is address (PC + 4 + displacement * 2). The PC source value is the BF/S instruction address. As the 8-bit displacement is multiplied by two after sign-extension, the branch destination can be located in the range from -256 to +254 bytes from the BF/S instruction.
Note
As this is a delayed branch instruction, when the branch condition is satisfied, the instruction following this instruction is executed before the branch destination instruction.
Interrupts are not accepted between this instruction and the following instruction.
If the following instruction is a branch instruction, it is identified as a slot illegal instruction.
If this instruction is located in the delay slot immediately following a delayed branch instruction, it is identified as a slot illegal instruction.
If the branch destination cannot be reached, the branch must be handled by using BF/S in combination with a BRA or JMP instruction, for example.
Operation
void BFS (int d) { int disp; unsigned int temp; temp = PC; if ((d & 0x80) == 0) disp = (0x000000FF & d); else disp = (0xFFFFFF00 | d);
if (T == 0) PC = PC + 4 + (disp << 1); else PC += 4;
Delay_Slot (temp + 2); }
Possible Exceptions
- Slot illegal instruction exception
SH1 SH2 SH3 SH4 SH4A SH2A
bt label
If T = 1: disp*2 + PC + 4 -> PC Else: nop
10001001dddddddd
BR BR
1 1 1 1 1-3 1/3
1/3 1/3 1/3 1/2 1 1/3
Description
This is a conditional branch instruction that references the T bit. The branch is taken if T = 1, and not taken if T = 0. The branch destination is address (PC + 4 + displacement * 2). The PC source value is the BT instruction address. As the 8-bit displacement is multiplied by two after sign-extension, the branch destination can be located in the range from -256 to +254 bytes from the BT instruction.
Note
If the branch destination cannot be reached, the branch must be handled by using BT in combination with a BRA or JMP instruction, for example.
On some SH4 implementations a branch with a displacement value of zero does not cause the pipeline I-stage to be stalled even if the branch is taken. This can be utilized for efficient conditional operations.
On some SH2E implementations (SH7055) there is an FPU related hardware bug which affects this instruction. The recommended workaround is to use bt/s with a nop in the delay slot. See also documents "sh2eoc.pdf" and "win_update_a.pdf".
Operation
void BT (int d) { int disp; if ((d & 0x80) == 0) disp = (0x000000FF & d); else disp = (0xFFFFFF00 | d);
if (T == 1) PC = PC + 4 + (disp << 1); else PC += 2; }
Possible Exceptions
- Slot illegal instruction exception
SH2 SH3 SH4 SH4A SH2A
bt/s label
If T = 1: disp*2 + PC + 4 -> PC Else: nop (Delayed branch)
10001101dddddddd
BR BR
1 1 1 1-3 1/2
1/2 1/2 1/2 1 1/2
Description
This is a conditional branch instruction that references the T bit. The branch is taken if T = 1, and not taken if T = 0. The PC source value is the BT/S instruction address. As the 8-bit displacement is multiplied by two after sign-extension, the branch destination can be located in the range from -256 to +254 bytes from the BT/S instruction.
Note
As this is a delayed branch instruction, when the branch condition is satisfied, the instruction following this instruction is executed before the branch destination instruction.
Interrupts are not accepted between this instruction and the following instruction.
If the following instruction is a branch instruction, it is identified as a slot illegal instruction.
If the branch destination cannot be reached, the branch must be handled by using BT/S in combination with a BRA or JMP instruction, for example.
Operation
void BTS (int d) { int disp; unsigned temp; temp = PC;
if ((d & 0x80) == 0) disp = (0x000000FF & d); else disp = (0xFFFFFF00 | d);
if (T == 1) PC = PC + 4 + (disp << 1); else PC += 4;
Delay_Slot (temp + 2); }
Possible Exceptions
- Slot illegal instruction exception
SH1 SH2 SH3 SH4 SH4A SH2A
bra label
disp*2 + PC + 4 -> PC (Delayed branch)
1010dddddddddddd
BR BR
1 1 1 1 1-3 2
2 2 2 2 1 2
Description
This is an unconditional branch instruction. The branch destination is address (PC + 4 + displacement * 2). The PC source value is the BRA instruction address. As the 12-bit displacement is multiplied by two after sign-extension, the branch destination can be located in the range from -4096 to +4094 bytes from the BRA instruction. If the branch destination cannot be reached, this branch can be performed with a JMP instruction.
Note
As this is a delayed branch instruction, the instruction following this instruction is executed before the branch destination instruction.
Interrupts are not accepted between this instruction and the following instruction.
If the following instruction is a branch instruction, it is identified as a slot illegal instruction.
Operation
void BRA (int d) { int disp; unsigned int temp; temp = PC;
if ((d & 0x800) == 0) disp = (0x00000FFF & d); else disp = (0xFFFFF000 | d);
PC = PC + 4 + (disp << 1); Delay_Slot(temp + 2); }
Possible Exceptions
- Slot illegal instruction exception
SH2 SH3 SH4 SH4A SH2A
braf Rm
Rm + PC + 4 -> PC (Delayed branch)
0000mmmm00100011
CO BR
1 1 2 4 2
2 2 3 1 2
Description
This is an unconditional branch instruction. The branch destination is address (PC + 4 + Rm).
Note
As this is a delayed branch instruction, the instruction following this instruction is executed before the branch destination instruction.
Interrupts are not accepted between this instruction and the following instruction.
If the following instruction is a branch instruction, it is identified as a slot illegal instruction.
Operation
void BRAF (int m) { unsigned int temp; temp = PC; PC = PC + 4 + R[m]; Delay_Slot (temp + 2); }
Possible Exceptions
- Slot illegal instruction exception
SH1 SH2 SH3 SH4 SH4A SH2A
bsr label
PC + 4 -> PR, disp*2 + PC + 4 -> PC (Delayed branch)
1011dddddddddddd
BR BR
1 1 1 1 1-3 2
2 2 2 2 1 2
Description
Branches to address (PC + 4 + displacement * 2), and stores address (PC + 4) in PR. The PC source value is the BSR instruction address. As the 12-bit displacement is multiplied by two after sign-extension, the branch destination can be located in the range from -4096 to +4094 bytes from the BSR instruction. If the branch destination cannot be reached, this branch can be performed with a JSR instruction.
Note
As this is a delayed branch instruction, the instruction following this instruction is executed before the branch destination instruction.
Interrupts are not accepted between this instruction and the following instruction.
If the following instruction is a branch instruction, it is identified as a slot illegal instruction.
Operation
void BSR (int d) { int disp; unsigned int temp; temp = PC;
if ((d & 0x800) == 0) disp = (0x00000FFF & d); else disp = (0xFFFFF000 | d);
PR = PC + 4; PC = PC + 4 + (disp << 1); Delay_Slot (temp + 2); }
Possible Exceptions
- Slot illegal instruction exception
SH2 SH3 SH4 SH4A SH2A
bsrf Rm
PC + 4 -> PR, Rm + PC + 4 -> PC (Delayed branch)
0000mmmm00000011
CO BR
1 1 2 4 2
2 2 3 1 2
Description
Branches to address (PC + 4 + Rm), and stores address (PC + 4) in PR. The PC source value is the BSRF instruction address. The branch destination address is the result of adding the 32-bit contents of general register Rm to PC + 4.
Note
As this is a delayed branch instruction, the instruction following this instruction is executed before the branch destination instruction.
Interrupts are not accepted between this instruction and the following instruction.
If the following instruction is a branch instruction, it is identified as a slot illegal instruction.
Operation
void BSRF (int m) { unsigned int temp; temp = PC; PR = PC + 4; PC = PC + 4 + R[m]; Delay_Slot (temp + 2); }
Possible Exceptions
- Slot illegal instruction exception
SH1 SH2 SH3 SH4 SH4A SH2A
jmp @Rm
Rm -> PC (Delayed branch)
0100mmmm00101011
CO BR
1 1 1 2 4 2
2 2 2 3 1 2
Description
Unconditionally makes a delayed branch to the address specified by Rm.
Note
As this is a delayed branch instruction, the instruction following this instruction is executed before the branch destination instruction.
Interrupts are not accepted between this instruction and the following instruction.
If the following instruction is a branch instruction, it is identified as a slot illegal instruction.
Operation
void JMP (int m) { unsigned int temp; temp = PC; PC = R[m]; Delay_Slot (temp + 2); }
Possible Exceptions
- Slot illegal instruction exception
SH1 SH2 SH3 SH4 SH4A SH2A
jsr @Rm
PC + 4 -> PR, Rm -> PC (Delayed branch)
0100mmmm00001011
CO BR
1 1 1 2 4 2
2 2 2 3 1 2
Description
Makes a delayed branch to the subroutine procedure at the specified address after execution of the following instruction. Return address (PC + 4) is saved in PR, and a branch is made to the address indicated by general register Rm. JSR is used in combination with RTS for subroutine procedure calls.
Note
As this is a delayed branch instruction, the instruction following this instruction is executed before the branch destination instruction.
Interrupts are not accepted between this instruction and the following instruction.
If the following instruction is a branch instruction, it is identified as a slot illegal instruction.
Operation
void JSR (int m) { unsigned int temp; temp = PC; PR = PC + 4; PC = R[m]; Delay_Slot (temp + 2); }
Possible Exceptions
- Slot illegal instruction exception
SH2A
jsr/n @Rm
PC + 2 -> PR, Rm -> PC
0100mmmm01001011
3
3
Description
Branches to a subroutine procedure at the designated address. The contents of PC are stored in PR and execution branches to the address indicated by the contents of general register Rm as 32-bit data. The stored contents of PC indicate the starting address of the second instruction after the present instruction. This instruction is used with RTS as a subroutine procedure call.
Note
This is not a delayed branch instruction.
Operation
void JSRN (int m) { unsigned long temp; temp = PC; PR = PC + 2; PC = R[m]; }
Possible Exceptions
- Slot illegal instruction exception
SH2A
jsr/n @@(disp8,TBR)
PC + 2 -> PR, (disp*4 + TBR) -> PC
10000011dddddddd
5
5
Description
Branches to a subroutine procedure at the designated address. The contents of PC are stored in PR and execution branches to the address indicated by the address read from memory address (disp × 4 + TBR). The stored contents of PC indicate the starting address of the second instruction after the present instruction. This instruction is used with RTS as a subroutine procedure call.
Note
This is not a delayed branch instruction.
Operation
void JSRNM (int d) { long disp = (0x000000FF & d); PR = PC + 2; PC = Read_32 (TBR + (disp << 2)); }
Possible Exceptions
- Slot illegal instruction exception
SH1 SH2 SH3 SH4 SH4A SH2A
rts
PR -> PC Delayed branch
0000000000001011
CO BR
1 1 1 2 1-4 2
2 2 2 3 1 2
Description
Returns from a subroutine procedure by restoring the PC from PR. Processing continues from the address indicated by the restored PC value. This instruction can be used to return from a subroutine procedure called by a BSR or JSR instruction to the source of the call.
Note
As this is a delayed branch instruction, the instruction following this instruction is executed before the branch destination instruction.
Interrupts are not accepted between this instruction and the following instruction.
If the following instruction is a branch instruction, it is identified as a slot illegal instruction.
The instruction that restores PR must be executed before the RTS instruction. This restore instruction cannot be in the RTS delay slot.
Operation
void RTS (void) { unsigned int temp; temp = PC; PC = PR; Delay_Slot (temp + 2); }
Possible Exceptions
- Slot illegal instruction exception
SH2A
rts/n
PR -> PC
0000000001101011
3
3
Description
Performs a return from a subroutine procedure. That is, the PC is restored from PR, and processing is resumed from the address indicated by the PC. This instruction enables a return to be made from a subroutine procedure called by a BSR or JSR instruction to the origin of the call.
Note
This is not a delayed branch instruction.
Operation
void RTSN (void) { PC = PR; }
Possible Exceptions
- Slot illegal instruction exception
SH2A
rtv/n Rm
Rm -> R0, PR -> PC
0000mmmm01111011
3
3
Description
Performs a return from a subroutine procedure after a transfer from specified general register Rm to R0. That is, after the Rm value is stored in R0, the PC is restored from PR, and processing is resumed from the address indicated by the PC. This instruction enables a return to be made from a subroutine procedure called by a BSR or JSR instruction to the origin of the call.
Note
This is not a delayed branch instruction.
Operation
void RTVN (int m) { R[0] = R[m]; PC = PR; }
Possible Exceptions
- Slot illegal instruction exception
System Control Instructions
SH1 SH2 SH3 SH4 SH4A SH2A
clrmac
0 -> MACH, 0 -> MACL
0000000000101000
CO EX
1 1 1 1 1 1
1 1 1 3 1 1
Description
Clears the MACH and MACL registers.
Operation
void CLRMAC (void) { MACH = 0; MACL = 0; PC += 2; }
SH3 SH4 SH4A
clrs
0 -> S
0000000001001000
CO EX
1 1 1
1 1 1
Description
Clears the S bit to 0.
Operation
void CLRS (void) { S = 0; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
clrt
0 -> T
0000000000001000
0
MT EX
1 1 1 1 1 1
1 1 1 1 1 1
Description
Clears the T bit.
Operation
void CLRT (void) { T = 0; PC += 2; }
SH4A
icbi @Rn
Invalidate instruction cache block indicated by logical address
0000nnnn11100011
CO
16
13
Description
Accesses the instruction cache at the effective address indicated by the contents of Rn. When the cache is hit, the corresponding cache block is invalidated (the V bit is cleared to 0). At this time, write-back is not performed. No operation is performed in the case of a cache miss or access to a non-cache area.
Note
When a program is overwriting RAM to modify its own execution, the corresponding block of the instruction cache should be invalidated by the ICBI instruction. This prevents execution of the program from the instruction cache, where the non-overwritten instructions are stored.
Operation
void ICBI (int n) { invalidate_instruction_cache_block (R[n]); PC += 2; }
Possible Exceptions
- Instruction TLB multiple-hit exception
- Instruction TLB miss exception
- Instruction TLB protection violation exception
- Instruction address error
- Slot illegal instruction exception
Exceptions may occur when invalidation is not performed.
SH2A
ldbank @Rm,R0
(Specified register bank entry) -> R0
0100mmmm11100101
6
5
Description
The register bank entry indicated by the contents of general register Rm is transferred to general register R0. The register bank number and register stored in the bank are specified by general register Rm.
Note
The architecture supports a maximum of 512 banks. However, the number of banks differs depending on the product.
Operation
void LDBANK (int m) { R[0] = Read_Bank_32 (R[m]); PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A Privileged
ldc Rm,SR
Rm -> SR
0100mmmm00001110
LSB
CO CO
1 1 1 4 7 3
1 1 5 4 4 2
Description
Stores the source operand in the control register SR.
Note
This instruction is only usable in privileged mode. Issuing this instruction in user mode will cause an illegal instruction exception.
Operation
void LDCSR (int m) { #if SH1 || SH2 || SH2 || SH3 SR = R[m] & 0x0FFF0FFF;
#elif SH2A SR = R[m] & 0x000063F3;
#elif SH4 || SH4A SR = R[m] & 0x700083F3;
#endif
PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH1 SH2 SH3 SH4 SH4A SH2A Privileged
ldc.l @Rm+,SR
(Rm) -> SR, Rm+4 -> Rm
0100mmmm00000111
LSB
CO CO
1 1 2 4 9 5
3 3 7 4/4 4 4
Description
Stores the source operand in the control register SR.
Note
This instruction is only usable in privileged mode. Issuing this instruction in user mode will cause an illegal instruction exception.
Operation
void LDCMSR (int m) { #if SH1 || SH2 || SH2 || SH3 SR = Read_32 (R[m]) & 0x0FFF0FFF;
#elif SH2A SR = Read_32 (R[m]) & 0x000063F3;
#elif SH4 || SH4A SR = Read_32 (R[m]) & 0x700083F3;
#endif
R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
SH2A
ldc Rm,TBR
Rm -> TBR
0100mmmm01001010
1
1
Description
Stores a source operand in control register TBR.
Operation
void LDCTBR (int m) { TBR = R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
ldc Rm,GBR
Rm -> GBR
0100mmmm00011110
CO LS
1 1 1 3 1 1
1 1 1/3 3 1 1
Description
Stores a source operand in control register GBR.
Note
This instruction can also be issued in user mode.
Operation
void LDCGBR (int m) { GBR = R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
ldc.l @Rm+,GBR
(Rm) -> GBR, Rm+4 -> Rm
0100mmmm00010111
CO LS
1 1 1 3 1 1
3 3 1/5 3/3 1 2
Description
Stores a source operand in control register GBR.
Note
This instruction can also be issued in user mode.
Operation
void LDCMGBR (int m) { GBR = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A Privileged
ldc Rm,VBR
Rm -> VBR
0100mmmm00101110
CO LS
1 1 1 1 1 1
1 1 1/3 3 1 1
Description
Stores a source operand in control register VBR.
Operation
void LDCVBR (int m) { VBR = R[m]; PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH1 SH2 SH3 SH4 SH4A SH2A Privileged
ldc.l @Rm+,VBR
(Rm) -> VBR, Rm+4 -> Rm
0100mmmm00100111
CO LS
1 1 1 1 1 1
3 3 1/5 1/3 1 2
Description
Stores a source operand in control register VBR.
Operation
void LDCMVBR (int m) { VBR = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
DSP
ldc Rm,MOD
Rm -> MOD
0100mmmm01011110
1
1/3
Description
Stores a source operand in control register MOD.
Note
On the SH-DSP the latency of this instruction is 1 cycle.
Operation
void LDCMOD (int m) { MOD = R[m]; PC += 2; }
DSP
ldc.l @Rm+,MOD
(Rm) -> MOD, Rm+4 -> Rm
0100mmmm01010111
1
1/5
Description
Stores a source operand in control register MOD.
Note
On the SH-DSP the latency of this instruction is 3 cycles.
Operation
void LDCMMOD (int m) { MOD = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data address error
DSP
ldc Rm,RE
Rm -> RE
0100mmmm01111110
1
1/3
Description
Stores a source operand in control register RE.
Note
On the SH-DSP the latency of this instruction is 1 cycle.
Operation
void LDCRE (int m) { RE = R[m]; PC += 2; }
DSP
ldc.l @Rm+,RE
(Rm) -> RE, Rm+4 -> Rm
0100mmmm01110111
1
1/5
Description
Stores a source operand in control register RE.
Note
On the SH-DSP the latency of this instruction is 3 cycles.
Operation
void LDCMRE (int m) { RE = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data address error
DSP
ldc Rm,RS
Rm -> RS
0100mmmm01101110
1
1/3
Description
Stores a source operand in control register RS.
Note
On the SH-DSP the latency of this instruction is 1 cycle.
Operation
void LDCRS (int m) { RS = R[m]; PC += 2; }
DSP
ldc.l @Rm+,RS
(Rm) -> RS, Rm+4 -> Rm
0100mmmm01100111
1
1/5
Description
Stores a source operand in control register RS.
Note
On the SH-DSP the latency of this instruction is 3 cycles.
Operation
void LDCMRS (int m) { RS = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data address error
SH4A Privileged
ldc Rm,SGR
Rm -> SGR
0100mmmm00111010
CO
4
4
Description
Stores a source operand in control register SGR.
Note
Not sure whether it is also available on SH4. It is not marked as new instruction for SH4A but is also not listed in SH4 manuals.
Operation
void LDCSGR (int m) { SGR = R[m]; PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH4A Privileged
ldc.l @Rm+,SGR
(Rm) -> SGR, Rm+4 -> Rm
0100mmmm00110110
CO
4
4
Description
Stores a source operand in control register SGR.
Note
Not sure whether it is also available on SH4. It is not marked as new instruction for SH4A but is also not listed in SH4 manuals.
Operation
void LDCMSGR (int m) { SGR = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
SH3 SH4 SH4A Privileged
ldc Rm,SSR
Rm -> SSR
0100mmmm00111110
CO LS
1 1 1
1/3 3 1
Description
Stores a source operand in control register SSR.
Operation
void LDCSSR (int m) { SSR = R[m], PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH3 SH4 SH4A Privileged
ldc.l @Rm+,SSR
(Rm) -> SSR, Rm+4 -> Rm
0100mmmm00110111
CO LS
1 1 1
1/5 1/3 1
Description
Stores a source operand in control register SSR.
Operation
void LDCMSSR (int m) { SSR = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
SH3 SH4 SH4A Privileged
ldc Rm,SPC
Rm -> SPC
0100mmmm01001110
CO LS
1 3 1
1/3 1 1
Description
Stores a source operand in control register SPC.
Operation
void LDCSPC (int m) { SPC = R[m]; PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH3 SH4 SH4A Privileged
ldc.l @Rm+,SPC
(Rm) -> SPC, Rm+4 -> Rm
0100mmmm01000111
CO LS
1 1 1
1/5 1/3 1
Description
Stores a source operand in control register SPC.
Operation
void LDCMSPC (int m) { SPC = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
SH4 SH4A Privileged
ldc Rm,DBR
Rm -> DBR
0100mmmm11111010
CO CO
1 4
3 4
Description
Stores a source operand in control register DBR.
Operation
void LDCDBR (int m) { DBR = R[m]; PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH4 SH4A Privileged
ldc.l @Rm+,DBR
(Rm) -> DBR, Rm+4 -> Rm
0100mmmm11110110
CO CO
1 4
1/3 4
Description
Stores a source operand in control register DBR.
Operation
void LDCMDBR (int m) { DBR = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
SH3 SH4 SH4A Privileged
ldc Rm,Rn_BANK
Rm -> Rn_BANK (n = 0-7)
0100mmmm1nnn1110
CO LS
1 1 1
1/3 3 1
Description
Stores a source operand in banked general register. Rn_BANK0 is accessed when the RB bit in the SR register is 1, and Rn_BANK1 is accessed when this bit is 0.
Operation
void LDCRn_BANK (int m) { Rn_BANK = R[m]; PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH3 SH4 SH4A Privileged
ldc.l @Rm+,Rn_BANK
(Rm) -> Rn_BANK, Rm+4 -> Rm
0100mmmm1nnn0111
CO LS
1 1 1
1/5 1/3 1
Description
Stores a source operand in banked general register. Rn_BANK0 is accessed when the RB bit in the SR register is 1, and Rn_BANK1 is accessed when this bit is 0.
Operation
void LDCMRn_BANK (int m) { Rn_BANK = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
DSP
ldre @(disp,PC)
disp*2 + PC -> RE
10001110dddddddd
1
3
Description
Stores the effective address of the source operand in the repeat end register RE. The effective address is an address specified by PC + displacement. The PC is the address four bytes after this instruction. The 8-bit displacement is sign-extended and doubled. Consequently, the relative interval from the branch destination is -256 to +254 bytes.
Note
The effective address value designated for the RE reregister is different from the actual repeat end address. Refer to RS and RE Design Rules, for more information.
When this instruction is arranged immediately after the delayed branch instruction, PC becomes the "first address +2" of the branch destination.
On the SH-DSP the latency of this instruction is 1 cycle.
Operation
void LDRE (int d) { long disp;
if ((d & 0x80) == 0) disp = (0x000000FF & (long)d); else disp = (0xFFFFFF00 | (long)d);
RE = PC + (disp << 1); PC += 2; }
Example
ldrs start ! Set repeat start address to RS
ldre end ! Set repeat end address to RE
setrc #32 ! Repeat 32 times from to
...
start:
...
...
...
end:
...
DSP
ldrs @(disp,PC)
disp*2 + PC -> RS
10001100dddddddd
1
3
Description
Stores the effective address of the source operand in the repeat start register RS. The effective address is an address specified by PC + displacement. The PC is the address four bytes after this instruction. The 8-bit displacement is sign-extended and doubled. Consequently, the relative interval from the branch destination is -256 to +254 bytes.
Note
When the instructions of the repeat (loop) program are below 3, the effective address value designated for the RS register is different from the actual repeat start address. Refer to "RS and RE setting rule", for more information. If this
instruction is arranged immediately after the delayed branch instruction, the PC becomes "the first address +2" of the branch destination.
On the SH-DSP the latency of this instruction is 1 cycle.
Operation
void LDRS (int d) { long disp;
if ((d & 0x80) == 0) disp = (0x000000FF & (long)d); else disp = (0xFFFFFF00 | (long)d);
RS = PC + (disp << 1); PC += 2; }
Example
ldrs start ! Set repeat start address to RS
ldre end ! Set repeat end address to RE
setrc #32 ! Repeat 32 times from to
...
start:
...
...
...
end:
...
SH1 SH2 SH3 SH4 SH4A SH2A
lds Rm,MACH
Rm -> MACH
0100mmmm00001010
CO LS
1 1 1 1 1 1
1 1 1 3 1 1
Description
Stores the source operand into the system register MACH.
Note
On SH1, only the lower 10 bits are stored in MACH.
On SH4, when an LDS to MAC* is followed by an STS.L MAC*,@-Rn instruction, the latency of the LDS to MAC* is 4 cycles. When an LDS to MAC* is followed by MAC.W/MAC.L, the latency of the LDS to MAC* is 1 cycle.
Operation
void LDSMACH (int m) { MACH = R[m];
#if SH1 if ((MACH & 0x00000200) == 0) MACH &= 0x000003FF; else MACH |= 0xFFFFFC00; #endif
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
lds.l @Rm+,MACH
(Rm) -> MACH, Rm+4 -> Rm
0100mmmm00000110
CO LS
1 1 1 1 1 1
1 1 1 1/3 1 2
Description
Stores the source operand into the system register MACH.
Note
On SH4, when an LDS to MAC* is followed by an STS.L MAC*,@-Rn instruction, the latency of the LDS to MAC* is 4 cycles. When an LDS to MAC* is followed by MAC.W/MAC.L, the latency of the LDS to MAC* is 1 cycle.
Operation
void LDSMMACH (int m) { MACH = Read_32 (R[m]);
#if SH1 if ((MACH & 0x00000200) == 0) MACH &= 0x000003FF; else MACH |= 0xFFFFFC00; #endif
R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
lds Rm,MACL
Rm -> MACL
0100mmmm00011010
CO LS
1 1 1 1 1 1
1 1 1 3 1 1
Description
Stores the source operand into the system register MACL.
Note
On SH4, when an LDS to MAC* is followed by an STS.L MAC*,@-Rn instruction, the latency of the LDS to MAC* is 4 cycles. When an LDS to MAC* is followed by MAC.W/MAC.L, the latency of the LDS to MAC* is 1 cycle.
Operation
void LDSMACL (int m) { MACL = R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
lds.l @Rm+,MACL
(Rm) -> MACL, Rm+4 -> Rm
0100mmmm00010110
CO LS
1 1 1 1 1 1
1 1 1 1/3 1 2
Description
Stores the source operand into the system register MACL.
Note
On SH4, when an LDS to MAC* is followed by an STS.L MAC*,@-Rn instruction, the latency of the LDS to MAC* is 4 cycles. When an LDS to MAC* is followed by MAC.W/MAC.L, the latency of the LDS to MAC* is 1 cycle.
Operation
void LDSMMACL (int m) { MACL = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
lds Rm,PR
Rm -> PR
0100mmmm00101010
CO LS
1 1 1 2 1 1
1 1 1 3 1 1
Description
Stores the source operand into the system register PR.
Operation
void LDSPR (int m) { PR = R[m]; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
lds.l @Rm+,PR
(Rm) -> PR, Rm+4 -> Rm
0100mmmm00100110
CO LS
1 1 1 2 1 1
1 1 1 2/3 1 2
Description
Stores the source operand into the system register PR.
Operation
void LDSMPR (int m) { PR = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
DSP
lds Rm,DSR
Rm -> DSR
0100mmmm01101010
1
1
Description
Stores the source operand into the DSP register DSR.
Operation
void LDSDSR (int m) { DSR = R[m] & 0x0000000F; PC += 2; }
DSP
lds.l @Rm+,DSR
(Rm) -> DSR, Rm+4 -> Rm
0100mmmm01100110
1
1/5
Description
Stores the source operand into the DSP register DSR.
Note
On the SH-DSP the latency of this instruction is 1 cycle.
Operation
void LDSMDSR (int m) { DSR = Read_32 (R[m]) & 0x0000000F; R[m] += 4; PC += 2; }
Possible Exceptions
- Data address error
DSP
lds Rm,A0
Rm -> A0
0100mmmm01110110
1
1
Description
Stores the source operand into the DSP register A0. The MSB of the data is copied into A0G.
Operation
void LDSA0 (int m) { A0 = R[m];
if ((A0 & 0x80000000) == 0) A0G = 0x00; else A0G = 0xFF;
PC+=2; }
DSP
lds.l @Rm+,A0
(Rm) -> A0, Rm+4 -> Rm
0100mmmm01110110
1
1
Description
Stores the source operand into the DSP register A0. The MSB of the data is copied into A0G.
Operation
void LDSMA0 (int m) { A0 = Read_32 (R[m]);
if ((A0 & 0x80000000) == 0) A0G = 0x00; else A0G = 0xFF;
R[m] += 4; PC += 2; }
Possible Exceptions
- Data address error
DSP
lds Rm,X0
Rm -> X0
0100mmmm10001010
1
1
Description
Stores the source operand into the DSP register X0.
Operation
void LDSX0 (int m) { X0 = R[m]; PC += 2; }
DSP
lds.l @Rm+,X0
(Rm) -> X0, Rm+4 -> Rm
0100nnnn10000110
1
1/5
Description
Stores the source operand into the DSP register X0.
Operation
void LDSMX0 (int m) { X0 = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data address error
DSP
lds Rm,X1
Rm -> X1
0100mmmm10011010
1
1
Description
Stores the source operand into the DSP register X1.
Operation
void LDSX1 (int m) { X1 = R[m]; PC += 2; }
DSP
lds.l @Rm+,X1
(Rm) -> X1, Rm+4 -> Rm
0100nnnn10010110
1
1/5
Description
Stores the source operand into the DSP register X1.
Operation
void LDSMX1 (int m) { X1 = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data address error
DSP
lds Rm,Y0
Rm -> Y0
0100mmmm10101010
1
1
Description
Stores the source operand into the DSP register Y0.
Operation
void LDSY0 (int m) { Y0 = R[m]; PC += 2; }
DSP
lds.l @Rm+,Y0
(Rm) -> Y0, Rm+4 -> Rm
0100nnnn10100110
1
1/5
Description
Stores the source operand into the DSP register Y0.
Operation
void LDSMY0 (int m) { Y0 = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data address error
DSP
lds Rm,Y1
Rm -> Y1
0100mmmm10111010
1
1
Description
Stores the source operand into the DSP register Y1.
Operation
void LDSY1 (int m) { Y1 = R[m]; PC += 2; }
DSP
lds.l @Rm+,Y1
(Rm) -> Y1, Rm+4 -> Rm
0100nnnn10110110
1
1
Description
Stores the source operand into the DSP register Y1.
Operation
void LDSMY1 (int m) { Y1 = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data address error
SH3 SH4 SH4A Privileged
ldtlb
PTEH/PTEL -> TLB
0000000000111000
CO CO
1 1 1
1 1 1
Description
Loads the contents of the PTEH/PTEL registers into the TLB (translation lookaside buffer) specified by MMUCR.URC (random counter field in the MMC control register).
LDTLB is a privileged instruction, and can only be used in privileged mode. Use of this instruction in user mode will cause an illegal instruction exception.
Note
As this instruction loads the contents of the PTEH/PTEL registers into a TLB, it should be used either with the MMU disabled, or in the P1 or P2 virtual space with the MMU enabled (see the MMU section of the applicable hardware manual for details).
After this instruction is issued, there must be at least one instruction between the LDTLB instruction and issuance of an instruction relating to address to the P0, U0, and P3 areas (i.e. BRAF, BSRF, JMP, JSR, RTS, or RTE).
If the instruction is issued in an exception handler, it should be at least two instructions prior to an RTE instruction that terminates the handler.
Operation
void LDTLB (void) { #if SH3 TLB_tag = PTEH; TLB_data = PTEL;
#elif SH4 TLB[MMUCR.URC].ASID = PTEH & 0x000000FF; TLB[MMUCR.URC].VPN = (PTEH & 0xFFFFFC00) >> 10; TLB[MMUCR.URC].PPN = (PTEH & 0x1FFFFC00) >> 10; TLB[MMUCR.URC].SZ = (PTEL & 0x00000080) >> 6 | (PTEL & 0x00000010) >> 4; TLB[MMUCR.URC].SH = (PTEH & 0x00000002) >> 1; TLB[MMUCR.URC].PR = (PTEH & 0x00000060) >> 5; TLB[MMUCR.URC].WT = (PTEH & 0x00000001); TLB[MMUCR.URC].C = (PTEH & 0x00000008) >> 3; TLB[MMUCR.URC].D = (PTEH & 0x00000004) >> 2; TLB[MMUCR.URC].V = (PTEH & 0x00000100) >> 8;
#endif
PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH4 SH4A
movca.l R0,@Rn
R0 -> (Rn) (without fetching cache block)
0000nnnn11000011
LS LS
1 1
3-7 1
Description
Stores the contents of general register R0 in the memory location indicated by effective address Rn. This instruction differs from other store instructions as follows.
If write-back is selected for the accessed memory, and a cache miss occurs, the cache block will be allocated but an R0 data write will be performed to that cache block without performing a block read. Other cache block contents are undefined.
Operation
void MOVCAL (int n) { if (is_write_back_memory (R[n]) && look_up_in_operand_cache (R[n]) == MISS) allocate_operand_cache_block (R[n]);
Write_32 (R[n], R[0]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
nop
No operation
0000000000001001
MT MT
1 1 1 1 1 1
1 1 1 0 1 0
Note
Increments the program counter (PC), advancing the processing flow to execution of the next instruction.
Operation
void NOP (void) { PC += 2; }
SH4 SH4A
ocbi @Rn
Invalidate operand cache block
0000nnnn10010011
LS LS
1 1
1-2 1
Description
Accesses data using the contents indicated by effective address Rn. In the case of a hit in the cache, the corresponding cache block is invalidated (the V bit is cleared to 0). If there is unwritten information (U bit = 1), write-back is not performed even if write-back mode is selected. No operation is performed in the case of a cache miss or an access to a non-cache area.
Operation
void OCBI (int n) { invalidate_operand_cache_block (R[n]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
Note that the above exceptions are generated even if OCBI does not operate.
SH4 SH4A
ocbp @Rn
Write back and invalidate operand cache block
0000nnnn10100011
LS LS
1 1
1-5 1
Description
Accesses data using the contents indicated by effective address Rn. If the cache is hit and there is unwritten information (U bit = 1), the corresponding cache block is written back to external memory and that block is invalidated (the V bit is cleared to 0). If there is no unwritten information (U bit = 0), the block is simply invalidated. No operation is performed in the case of a cache miss or an access to a non-cache area.
Operation
void OCBP (int n) { if (is_dirty_block (R[n])) write_back (R[n])
invalidate_operand_cache_block (R[n]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
Note that the above exceptions are generated even if OCBP does not operate.
SH4 SH4A
ocbwb @Rn
Write back operand cache block
0000nnnn10110011
LS LS
1 1
1-5 1
Description
Accesses data using the contents indicated by effective address Rn. If the cache is hit and there is unwritten information (U bit = 1), the corresponding cache block is written back to external memory and that block is cleaned (the U bit is cleared to 0). In other cases (i.e. in the case of a cache miss or an access to a non-cache area, or if the block is already clean), no operation is performed.
Operation
void OCBWB (int n) { if (is_dirty_block (R[n])) write_back (R[n]);
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
Note that the above exceptions are generated even if OCBWB does not operate.
SH3 SH4 SH4A SH2A
pref @Rn
(Rn) -> operand cache
0000nnnn10000011
LS LS
1 1 1 1
1/2 1 1 0
Description
SH4 and SH4A
Reads a 32-byte data block starting at a 32-byte boundary into the operand cache. The lower 5 bits of the address specified by Rn are masked to zero.
This instruction is also used to trigger a Store Queue write-back operation if the specified address points to the Store Queue area. For more information refer to Store Queues in the manual.
SH3 and SH2A
Reads a 16-byte data block into the cache. The address specified by Rn should be on 32-bit boundary. No address related error is detected in this instruction. In case of an error, the instruction operates as NOP.
Note
On products with no cache, this instruction is handled as a NOP instruction.
Operation
void PREF (int n) { prefetch_operand_cache_block (R[n]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
SH4A
prefi @Rn
Reads 32-byte instruction block into instruction cache
0000nnnn11010011
CO
13
10
Description
Reads a 32-byte block of data starting at a 32-byte boundary within the instruction cache. The lower 5 bits of the address specified by Rn are masked by zeroes.
This instruction does not generate data address error and MMU exceptions. In the event of an error, the PREFI instruction is treated as an NOP (no operation) instruction.
When the address to be prefetched is missing from UTLB or is protected, the PREFI instruction is treated as an NOP instruction and a TLB exception does not occur.
Note
This instruction can be used before the SLEEP command is issued to prefetch instructions for execution on return from the SLEEP state.
Operation
void PREFI (int n) { prefetch_instruction_cache_block (R[n]); PC += 2; }
Possible Exceptions
- Slot illegal instruction exception
SH2A
resbank
Bank -> R0 to R14, GBR, MACH, MACL, PR
0000000001011011
9/19
8/20
Description
Restores the last register saved to a register bank.
Note
The issue cycle count is 19 when a bank overflow has occured and the registers are restored from the stack.
Operation
void RESBANK (void) { int m; // Number of register bank to which a save was last performed.
if (BO == 0) { PR = Register_Bank[m].PR_BANK; GBR = Register_Bank[m].GBR_BANK; MACL = Register_Bank[m].MACL_BANK; MACH = Register_Bank[m].MACH_BANK;
for (int i = 0; i <= 14; i++)
R[i] = Register_Bank[m].R_BANK[i];
} else { for (int i = 0; i <= 14; i++) { R[i] = Read_32 (R[15]); R[15] += 4; }
PR = Read_32 (R[15]);
R[15] += 4;
GBR = Read_32 (R[15]);
R[15] += 4;
MACH = Read_32 (R[15]);
R[15] += 4;
MACL = Read_32 (R[15]);
R[15] += 4;
}
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A Privileged
rte
Delayed branch SH1*,SH2*: stack area -> PC/SR SH3*,SH4*: SSR/SPC -> SR/PC
0000000000101011
CO CO
1 1 1 5 5 6
4 4 4 5 4 5
Description
Returns from an exception or interrupt handling routine by restoring the PC and SR values. Program execution continues from the address specified by the restored PC value.
On SH3 and SH4 the PC and SR values are restored from SPC and SSR. The SR value accessed by the instruction in the RTE delay slot is the value restored from SSR by the RTE instruction. The SR and MD values defined prior to RTE execution are used to fetch the instruction in the RTE delay slot.
On SH1, SH2 and SH2A the PC and SR values are from the stack (R15).
Note
As this is a delayed branch instruction, the instruction following the RTE instruction is executed before the branch destination instruction.
Interrupts are not accepted between this instruction and the following instruction. An exception must not be generated by the instruction in this instruction's delay slot. If the following instruction is a branch instruction, it is identified as a slot illegal instruction.
If this instruction is located in the delay slot immediately following a delayed branch instruction, it is identified as a slot illegal instruction.
On SH3 and SH4 the SR value accessed by the instruction in the RTE delay slot is the value restored from SSR by the RTE instruction. The SR and MD values defined prior to RTE execution are used to fetch the instruction in the RTE delay slot.
Operation
void RTE (void) { unsigned long temp = PC;
#if SH1 || SH2 || SH2A PC = Read_32 (R[15]); R[15] += 4; SR = Read_32 (R[15]) & 0x000063F3; R[15] += 4;
#elif SH3 || SH4 || SH4A SR = SSR; PC = SPC;
#endif
Delay_Slot (temp + 2); }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
DSP
setrc Rn
Rn[11:0] -> RC (SR[27:16])
0100mmmm00010100
1
3
Description
Sets the repeat count to the SR register's RC counter. The bottom 12 bits of the general register Rn are used as the repeat count. Set repeat control flags to RF1, RF0 bits of the SR register. Use of the SETRC instruction is subject to any limitations. Refer to the DSP Repeat (Loop) Control section of the manual for more information.
Note
On the SH-DSP the latency of this instruction is 1 cycle.
Operation
void SETRC (int m) { long temp = (R[m] & 0x00000FFF) << 16; SR &= 0x00000FF3; SR |= temp; RF1 = Repeat_Control_Flag1; RF0 = Repeat_Control_Flag0; PC += 2; }
Example
ldrs start ! Set repeat start address to RS
ldre end ! Set repeat end address to RE
setrc r14 ! Repeat n times from to
...
start:
...
...
...
end:
...
DSP
setrc #imm
imm -> RC (SR[23:16]), 0 -> SR[27:24]
10000010iiiiiiii
1
3
Description
Sets the repeat count to the SR register's RC counter. The 8-bit immediate value is zero-extended and used as the repeat count. Set repeat control flags to RF1, RF0 bits of the SR register. Use of the SETRC instruction is subject to any limitations. Refer to the DSP Repeat (Loop) Control section of the manual for more information.
Note
On the SH-DSP the latency of this instruction is 1 cycle.
Operation
void SETRCI (int i) { long temp = ((long)i & 0x000000FF) << 16; SR &= 0x00000FFF; SR |= temp; RF1 = Repeat_Control_Flag1; RF0 = Repeat_Control_Flag0; PC += 2; }
Example
ldrs start ! Set repeat start address to RS
ldre end ! Set repeat end address to RE
setrc #32 ! Repeat 32 times from to
...
start:
...
...
...
end:
...
SH3 SH4 SH4A
sets
1 -> S
0000000001011000
CO EX
1 1 1
1 1 1
Description
Sets the S bit to 1.
Operation
void SETS (void) { S = 1; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
sett
1 -> T
0000000000011000
1
MT EX
1 1 1 1 1 1
1 1 1 1 1 0
Description
Sets the T bit to 1.
Operation
void SETT (void) { T = 1; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A Privileged
sleep
Sleep or standby
0000000000011011
CO CO
1 1 2 4 ud 5
3 3 4 4 ud 0
Description
Places the CPU in the power-down state.
In power-down mode, the CPU retains its internal state, but immediately stops executing instructions and waits for an interrupt request. When it receives an interrupt request, the CPU exits the power-down state.
SLEEP is a privileged instruction, and can only be used in privileged mode. Use of this instruction in user mode will cause an illegal instruction exception.
Note
SLEEP performance depends on the standby control register (STBCR). See Power-Down Modes in the target product's hardware manual, for details.
The number of cycles given is for the transition to sleep mode. "ud" means the number of cycles is undefined.
Some SH4 implementations have a hardware bug which restricts the instructions that should follow this instruction for safe operation. There are two recommended workarounds:
- Put 8 NOP instructions following the SLEEP instruction.
- Put 5 "OR R0,R0" instructions following the SLEEP instruction
For more information see the document "tnsh7456ae.pdf".
Operation
void SLEEP (void) { Sleep_standby(); }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH2A
stbank R0,@Rn
R0 -> (specified register bank entry)
0100nnnn11100001
7
6
Description
R0 is transferred to the register bank entry indicated by the contents of general register Rn. The register bank number and register stored in the bank are specified by general register Rn.
Note
The architecture supports a maximum of 512 banks. However, the number of banks differs depending on the product.
Operation
void STBANK (int n) { Write_Bank_32 (R[n], R[0]) PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A Privileged
stc SR,Rn
SR -> Rn
0000nnnn00000010
CO CO
1 1 1 2 1 2
1 1 1 2 1 2
Description
Stores control register SR in the destination.
Note
This instruction is only usable in privileged mode. Issuing this instruction in user mode will cause an illegal instruction exception.
Operation
void STCSR (int n) { R[n] = SR; PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH1 SH2 SH3 SH4 SH4A SH2A Privileged
stc.l SR,@-Rn
Rn-4 -> Rn, SR -> (Rn)
0100nnnn00000011
CO CO
1 1 1 2 1 2
2 2 1/2 2/2 1 2
Description
Stores control register SR in the destination.
Note
This instruction is only usable in privileged mode. Issuing this instruction in user mode will cause an illegal instruction exception.
Operation
void STCMSR (int n) { R[n] -= 4; Write_32 (R[n], SR); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
SH2A
stc TBR,Rn
TBR -> Rn
0000nnnn01001010
1
1
Description
Stores control register TBR in the destination.
Operation
void STCTBR (int n) { R[n] = TBR; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
stc GBR,Rn
GBR -> Rn
0000nnnn00010010
CO LS
1 1 1 2 1 1
1 1 1 2 1 1
Description
Stores control register GBR in the destination.
Note
This instruction can also be issued in user mode.
Operation
STCGBR (int n) { R[n] = GBR; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
stc.l GBR,@-Rn
Rn-4 -> Rn, GBR -> (Rn)
0100nnnn00010011
CO LS
1 1 1 2 1 1
2 2 1/2 2/2 1 1
Description
Stores control register GBR in the destination.
Note
This instruction can also be issued in user mode.
Operation
void STCMGBR (int n) { R[n] -= 4; Write_32 (R[n], GBR); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A Privileged
stc VBR,Rn
VBR -> Rn
0000nnnn00100010
CO LS
1 1 1 2 1 1
1 1 1 2 1 1
Description
Stores control register VBR in the destination.
Operation
void STCVBR (int n) { R[n] = VBR; PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH1 SH2 SH3 SH4 SH4A SH2A Privileged
stc.l VBR,@-Rn
Rn-4 -> Rn, VBR -> (Rn)
0100nnnn00100011
CO LS
1 1 1 2 1 1
2 2 1/2 2/2 1 1
Description
Stores control register VBR in the destination.
Operation
void STCMVBR (int n) { R[n] -= 4; Write_32 (R[n], VBR); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
DSP
stc MOD,Rn
MOD -> Rn
0000nnnn01010010
1
1
Description
Stores control register MOD in the destination.
Operation
void STCMOD (int n) { R[n] = MOD; PC += 2; }
DSP
stc.l MOD,@-Rn
Rn-4 -> Rn, MOD -> (Rn)
0100nnnn01010011
1
1/2
Description
Stores control register MOD in the destination.
Note
On the SH-DSP the latency of this instruction is 2 cycles.
Operation
void STCMMOD (int n) { R[n] -= 4; Write_32 (R[n], MOD); PC += 2; }
Possible Exceptions
- Data address error
DSP
stc RE,Rn
RE -> Rn
0000nnnn01110010
1
1
Description
Stores control register RE in the destination.
Operation
void STCRE (int n) { R[n] = RE; PC += 2; }
DSP
stc.l RE,@-Rn
Rn-4 -> Rn, RE -> (Rn)
0100nnnn01110011
1
1/2
Description
Stores control register RE in the destination.
Note
On the SH-DSP the latency of this instruction is 2 cycles.
Operation
void STCMRE (int n) { R[n] -= 4; Write_32 (R[n], RE); PC += 2; }
Possible Exceptions
- Data address error
DSP
stc RS,Rn
RS -> Rn
0000nnnn01100010
1
1
Description
Stores control register RS in the destination.
Operation
void STCRS (int n) { R[n] = RS; PC += 2; }
DSP
stc.l RS,@-Rn
Rn-4 -> Rn, RS -> (Rn)
0100nnnn01100011
1
1/2
Description
Stores control register RS in the destination.
Note
On the SH-DSP the latency of this instruction is 2 cycles.
Operation
void STCMRS (int n) { R[n] -= 4; Write_32 (R[n], RS); PC += 2; }
Possible Exceptions
- Data address error
SH4 SH4A Privileged
stc SGR,Rn
SGR -> Rn
0000nnnn00111010
CO LS
3 1
3 1
Description
Stores control register SGR in the destination.
Operation
void STCSGR (int n) { R[n] = SGR; PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH4 SH4A Privileged
stc.l SGR,@-Rn
Rn-4 -> Rn, SGR -> (Rn)
0100nnnn00110010
CO LS
3 1
3/3 1
Description
Stores control register SGR in the destination.
Operation
void STCMSGR (int n) { R[n] -= 4; Write_32 (R[n], SGR); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
SH3 SH4 SH4A Privileged
stc SSR,Rn
SSR -> Rn
0000nnnn00110010
CO LS
1 2 1
1 2 1
Description
Stores control register SSR in the destination.
Operation
void STCSSR (int n) { R[n] = SSR; PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH3 SH4 SH4A Privileged
stc.l SSR,@-Rn
Rn-4 -> Rn, SSR -> (Rn)
0100nnnn00110011
CO LS
1 2 1
1/2 2 1
Description
Stores control register SSR in the destination.
Operation
void STCMSSR (int n) { R[n] -= 4; Write_32 (R[n], SSR); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
SH3 SH4 SH4A Privileged
stc SPC,Rn
SPC -> Rn
0000nnnn01000010
CO LS
1 2 1
1 2 1
Description
Stores control register SPC in the destination.
Operation
void STCSPC (int n) { R[n] = SPC; PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH3 SH4 SH4A Privileged
stc.l SPC,@-Rn
Rn-4 -> Rn, SPC -> (Rn)
0100nnnn01000011
CO LS
2 1
2/2 1
Description
Stores control register SPC in the destination.
Operation
void STCMSPC (int n) { R[n] -= 4; Write_32 (R[n], SPC); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
SH4 SH4A Privileged
stc DBR,Rn
DBR -> Rn
0000nnnn11111010
CO LS
2 1
2 1
Description
Stores control register DBR in the destination.
Operation
void STCDBR (int n) { R[n] = DBR; PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH4 SH4A Privileged
stc.l DBR,@-Rn
Rn-4 -> Rn, DBR -> (Rn)
0100nnnn11110010
CO LS
2 1
2/2 1
Description
Stores control register DBR in the destination.
Operation
void STCMDBR (int n) { R[n] -= 4; Write_32 (R[n], DBR); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
SH3 SH4 SH4A Privileged
stc Rm_BANK,Rn
Rm_BANK -> Rn (m = 0-7)
0000nnnn1mmm0010
CO LS
1 2 1
1 2 1
Description
Stores a banked general register in the destination. Rn_BANK0 is accessed when the RB bit in the SR register is 1, and Rn_BANK1 is accessed when this bit is 0.
Operation
void STCRm_BANK (int n) { R[n] = Rm_BANK; PC += 2; }
Possible Exceptions
- General illegal instruction exception
- Slot illegal instruction exception
SH3 SH4 SH4A Privileged
stc.l Rm_BANK,@-Rn
Rn-4 -> Rn, Rm_BANK -> (Rn) (m = 0-7)
0100nnnn1mmm0011
CO LS
2 2 1
2 2/2 1
Description
Stores a banked general register in the destination. Rn_BANK0 is accessed when the RB bit in the SR register is 1, and Rn_BANK1 is accessed when this bit is 0.
Operation
void STCMRm_BANK (int n) { R[n] -= 4; Write_32 (R[n], Rm_BANK); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
- General illegal instruction exception
- Slot illegal instruction exception
SH1 SH2 SH3 SH4 SH4A SH2A
sts MACH,Rn
MACH -> Rn
0000nnnn00001010
CO LS
1 1 1 1 1 1
1 1 1 3 1 2
Description
Stores system register MACH in the destination.
Note
On SH1, the value of bit 9 is transferred to and stored in the higher 22 bits (bits 31 to 10) of the destination.
On SH4, when an LDS to MAC* is followed by an STS.L MAC*,@-Rn instruction, the latency of the LDS to MAC* is 4 cycles.
Operation
void STSMACH (int n) { R[n] = MACH;
#if SH1 if ((R[n] & 0x00000200) == 0) R[n] &= 0x000003FF; else R[n] |= 0xFFFFFC00;
#endif
PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
sts.l MACH,@-Rn
Rn-4 -> Rn, MACH -> (Rn)
0100nnnn00000010
CO LS
1 1 1 1 1 1
1 1 1 1/1 1 1
Description
Stores system register MACH in the destination.
Note
On SH1, the value of bit 9 is transferred to and stored in the higher 22 bits (bits 31 to 10) of the destination.
On SH4, when an LDS to MAC* is followed by an STS.L MAC*,@-Rn instruction, the latency of the LDS to MAC* is 4 cycles.
Operation
void STSMMACH (int n) { R[n] -= 4;
#if SH1 if ((MACH & 0x00000200) == 0) Write_32 (R[n], MACH & 0x000003FF); else Write_32 (R[n], MACH | 0xFFFFFC00)
#else Write_32 (R[n], MACH);
#endif
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
sts MACL,Rn
MACL -> Rn
0000nnnn00011010
CO LS
1 1 1 1 1 1
1 1 1 3 1 2
Description
Stores system register MACL in the destination.
Note
On SH4, when an LDS to MAC* is followed by an STS.L MAC*,@-Rn instruction, the latency of the LDS to MAC* is 4 cycles.
Operation
void STSMACL (int n) { R[n] = MACL; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
sts.l MACL,@-Rn
Rn-4 -> Rn, MACL -> (Rn)
0100nnnn00010010
CO LS
1 1 1 1 1 1
1 1 1 1/1 1 1
Description
Stores system register MACL in the destination.
Note
On SH4, when an LDS to MAC* is followed by an STS.L MAC*,@-Rn instruction, the latency of the LDS to MAC* is 4 cycles.
Operation
void STSMMACL (int n) { R[n] -= 4; Write_32 (R[n], MACL); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
SH1 SH2 SH3 SH4 SH4A SH2A
sts PR,Rn
PR -> Rn
0000nnnn00101010
CO LS
1 1 1 2 1 1
1 1 1 2 1 1
Description
Stores system register PR in the destination.
Operation
void STSPR (int n) { R[n] = PR; PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
sts.l PR,@-Rn
Rn-4 -> Rn, PR -> (Rn)
0100nnnn00100010
CO LS
1 1 1 2 1 1
1 1 1 2/2 1 1
Description
Stores system register PR in the destination.
Operation
void STSMPR (int n) { R[n] -= 4; Write_32 (R[n], PR); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Initial page write exception
- Data address error
DSP
sts DSR,Rn
DSR -> Rn
0000nnnn01101010
1
1
Description
Stores DSP register DSR in the destination.
Operation
void STSDSR (int n) { R[n] = DSR; PC += 2; }
DSP
sts.l DSR,@-Rn
Rn-4 -> Rn, DSR -> (Rn)
0100nnnn01100010
1
1
Description
Stores DSP register DSR in the destination.
Operation
void STSMDSR (int n) { R[n] -= 4; Write_32 (R[n], DSR); PC += 2; }
Possible Exceptions
- Data address error
DSP
sts A0,Rn
A0 -> Rn
0000nnnn01111010
1
1
Description
Stores DSP register A0 in the destination.
Operation
void STSA0 (int n) { R[n] = A0; PC += 2; }
DSP
sts.l A0,@-Rn
Rn-4 -> Rn, A0 -> (Rn)
0100nnnn01100010
1
1
Description
Stores DSP register A0 in the destination.
Operation
void STSMA0 (int n) { R[n] -= 4; Write_32 (R[n], A0); PC += 2; }
Possible Exceptions
- Data address error
DSP
sts X0,Rn
X0 -> Rn
0000nnnn10001010
1
1
Description
Stores DSP register X0 in the destination.
Operation
void STSX0 (int n) { R[n] = X0; PC += 2; }
DSP
sts.l X0,@-Rn
Rn-4 -> Rn, X0 -> (Rn)
0100nnnn10000010
1
1
Description
Stores DSP register X0 in the destination.
Operation
void STSMX0 (int n) { R[n] -= 4; Write_32 (R[n], X0); PC += 2; }
Possible Exceptions
- Data address error
DSP
sts X1,Rn
X1 -> Rn
0000nnnn10011010
1
1
Description
Stores DSP register X1 in the destination.
Operation
void STSX1 (int n) { R[n] = X1; PC += 2; }
DSP
sts.l X1,@-Rn
Rn-4 -> Rn, X1 -> (Rn)
0100nnnn10010010
1
1
Description
Stores DSP register X1 in the destination.
Operation
void STSMX1 (int n) { R[n] -= 4; Write_32 (R[n], X1); PC += 2; }
Possible Exceptions
- Data address error
DSP
sts Y0,Rn
Y0 -> Rn
0000nnnn10101010
1
1
Description
Stores DSP register Y0 in the destination.
Operation
void STSY0 (int n) { R[n] = Y0; PC += 2; }
DSP
sts.l Y0,@-Rn
Rn-4 -> Rn, Y0 -> (Rn)
0100nnnn10100010
1
1
Description
Stores DSP register Y0 in the destination.
Operation
void STSMY0 (int n) { R[n] -= 4; Write_32 (R[n], Y0); PC += 2; }
Possible Exceptions
- Data address error
DSP
sts Y1,Rn
Y1 -> Rn
0000nnnn10111010
1
1
Description
Stores DSP register Y1 in the destination.
Operation
void STSY1 (int n) { R[n] = Y1; PC += 2; }
DSP
sts.l Y1,@-Rn
Rn-4 -> Rn, Y1 -> (Rn)
0100nnnn10110010
1
1
Description
Stores DSP register Y1 in the destination.
Operation
void STSMY1 (int n) { R[n] -= 4; Write_32 (R[n], Y1); PC += 2; }
Possible Exceptions
- Data address error
SH4A
synco
Prevents the next instruction from being issued until instructions issued before this instruction has been completed.
0000000010101011
CO
ud
ud
Description
This instruction is used to synchronize data operations. When this instruction is executed, the subsequent bus accesses are not executed until the execution of all preceding bus accesses has been completed.
Note
The SYNCO instruction can not guarantee the ordering of receipt timing which is notified by the memory-mapped peripheral resources through the method except bus when the register is changed by bus accesses. Refer to the description of each registers to guarantee this ordering.
Common example usages are:
- Ordering access to memory areas which are shared with other memory users
- Flushing all write buffers
- Stopping memory-access operations from merging and becoming ineffective
- Waiting for the completion of cache-control instructions
Operation
void SYNCO (void) { synchronize_data_operaiton (); PC += 2; }
SH1 SH2 SH3 SH4 SH4A SH2A
trapa #imm
SH1*,SH2*: PC/SR -> stack area, (imm*4 + VBR) -> PC SH3*,SH4*: PC/SR -> SPC/SSR, imm*4 -> TRA, 0x160 -> EXPEVT, VBR + 0x0100 -> PC
11000011iiiiiiii
CO CO
2 2 2 7 14 5
8 8 8 7 13 6
Description
Starts trap exception handling. SH1, SH2 and SH2A:
The PC and SR values are stored on the stack, and the program branches to an address specified by the vector. The vector is a memory address obtained by zero-extending the 8-bit immediate data and then quadrupling it. The PC is the start address of the next instruction. TRAPA and RTE are both used together for system calls.
SH3, SH4 and SH4A:
The values of (PC + 2), SR, and R15 are saved to SPC, SSR and SGR, and 8-bit immediate data is stored in the TRA register (bits 9 to 2). The processor mode is switched to privileged mode (the MD bit in SR is set to 1), and the BL bit and RB bit in SR are set to 1. As a result, exception and interrupt requests are masked (not accepted), and the BANK1 registers (R0_BANK1 to R7_BANK1) are selected. Exception code 0x160 is written to the EXPEVT register (bits 11 to 0). The program branches to address (VBR + 0x00000100), indicated by the sum of the VBR register contents and offset 0x00000100.
Note
Some SH4 implementations have a hardware bug which restricts the instructions that should follow this instruction for safe operation. There are two recommended workarounds:
- Put 8 NOP instructions following the TRAPA instruction.
- Put 5 "OR R0,R0" instructions following the TRAPA instruction
For more information see the document "tnsh7456ae.pdf".
Some SH2E implementations (SH7055) have an FPU related hardware bug which affects this instruction. The recommended workaround is to align the addresses of trapa handlers to 4 bytes and not to place any FPU or FPU related instructions at addresses 4n + 2 in the handler.
Operation
void TRAPA (int i) { int imm = (0x000000FF & i);
#if SH1 || SH2 || SH2A R[15] -= 4; Write_32 (R[15], SR); R[15] -= 4; Write_32 (R[15], PC + 2); PC = Read_32 (VBR + (imm << 2));
#elif SH3 || SH4 || SH4A TRA = imm << 2; SSR = SR; SPC = PC + 2; SGR = R15; SR.MD = 1; SR.BL = 1; SR.RB = 1; EXPEVT = 0x00000160; PC = VBR + 0x00000100;
#endif }
Possible Exceptions
- Unconditional trap
- Slot illegal instruction exception
32 Bit Floating-Point Data Transfer Instructions (FPSCR.SZ = 0)
SH2E SH3E SH4 SH4A SH2A
fmov FRm,FRn
FRm -> FRn
1111nnnnmmmm1100
LS LS
1 1 1 1 1
1 1 0 1 0
Description
Transfers FRm contents to FRn.
Operation
void FMOV (int m, int n) { FR[n] = FR[m]; PC += 2; }
SH2E SH3E SH4 SH4A SH2A
fmov.s @Rm,FRn
(Rm) -> FRn
1111nnnnmmmm1000
LS LS
1 1 1 1 1
1 1 2 1 0/2
Description
Transfers contents of memory at address indicated by Rm to FRn.
Operation
void FMOV_LOAD (int m, int n) { FR[n] = Read_32 (R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH2E SH3E SH4 SH4A SH2A
fmov.s FRm,@Rn
FRm -> (Rn)
1111nnnnmmmm1010
LS LS
1 1 1 1 1
1 1 1 1 0
Description
Transfers FRm contents to memory at address indicated by Rn.
Operation
void FMOV_STORE (int m, int n) { Write_32 (R[n], FR[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH2E SH3E SH4 SH4A SH2A
fmov.s @Rm+,FRn
(Rm) -> FRn, Rm+4 -> Rm
1111nnnnmmmm1001
LS LS
1 1 1 1 1
1 1 1/2 1 1/2
Description
Transfers contents of memory at address indicated by Rm to FRn, and adds 4 to Rm.
Operation
void FMOV_RESTORE (int m, int n) { FR[n] = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH2E SH3E SH4 SH4A SH2A
fmov.s FRm,@-Rn
Rn-4 -> Rn, FRm -> (Rn)
1111nnnnmmmm1011
LS LS
1 1 1 1 1
1 1 1/1 1 1/0
Description
Subtracts 4 from Rn, and transfers FRm contents to memory at address indicated by resulting Rn value.
Operation
void FMOV_SAVE (int m, int n) { Write_32 (R[n] - 4, FR[m]); R[n] -= 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH2E SH3E SH4 SH4A SH2A
fmov.s @(R0,Rm),FRn
(R0 + Rm) -> FRn
1111nnnnmmmm0110
LS LS
1 1 1 1 1
1 1 2 1 0/2
Description
Transfers contents of memory at address indicated by (R0 + Rm) to FRn.
Operation
void FMOV_INDEX_LOAD (int m, int n) { FR[n] = Read_32 (R[0] + R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH2E SH3E SH4 SH4A SH2A
fmov.s FRm,@(R0,Rn)
FRm -> (R0 + Rn)
1111nnnnmmmm0111
LS LS
1 1 1 1 1
1 1 1 1 0
Description
Transfers FRm contents to memory at address indicated by (R0 + Rn).
Operation
void FMOV_INDEX_STORE (int m, int n) { Write_32 (R[0] + R[n], FR[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH2A
fmov.s @(disp12,Rm),FRn
(disp*4 + Rm) -> FRn
0011nnnnmmmm0001 0111dddddddddddd
1
0/2
Description
Transfers memory contents at the address indicated by (disp + Rn) to FRn.
Operation
void FMOV_INDEX_DISP12_LOAD (int m, int n, int d) { long disp = (0x00000FFF & (long)d); FR[n] = Read_32 (R[m] + (disp << 2)); PC += 4; }
Possible Exceptions
- Data address error
SH2A
fmov.s FRm,@(disp12,Rn)
FRm -> (disp*4 + Rn)
0011nnnnmmmm0001 0011dddddddddddd
1
0
Description
Transfers FRm contents to memory at the address indicated by (disp + Rn).
Operation
void FMOV_INDEX_DISP12_STORE (int m, int n, int d) { long disp = (0x00000FFF & (long)d); Write_32 (R[n] + (disp << 2), FR[m]); PC += 4; }
Possible Exceptions
- Data address error
64 Bit Floating-Point Data Transfer Instructions (FPSCR.SZ = 1)
SH4 SH4A SH2A
fmov DRm,DRn
DRm -> DRn
1111nnn0mmm01100
LS LS
1 1 2
0 1 1
Description
Transfers DRm contents to DRn.
Operation
void FMOV_DR (int m, int n) { DR[n >> 1] = DR[m >> 1]; PC += 2; }
SH4 SH4A
fmov DRm,XDn
DRm -> XDn
1111nnn1mmm01100
LS LS
1 1
0 1
Description
Transfers DRm contents to XDn.
Operation
void FMOV_DRXD (int m, int n) { XD[n >> 1] = DR[m >> 1]; PC += 2; }
SH4 SH4A
fmov XDm,DRn
XDm -> DRn
1111nnn0mmm11100
LS LS
1 1
0 1
Description
Transfers XDm contents to DRn.
Operation
void FMOV_XDDR (int m, int n) { DR[n >> 1] = XD[m >> 1]; PC += 2; }
SH4 SH4A
fmov XDm,XDn
XDm -> XDn
1111nnn1mmm11100
LS LS
1 1
0 1
Description
Transfers XDm contents to XDn.
Operation
void FMOV_XDXD (int m, int n) { XD[n >> 1] = XD[m >> 1]; PC += 2; }
SH4 SH4A SH2A
fmov.d @Rm,DRn
(Rm) -> DRn
1111nnn0mmmm1000
LS LS
1 1 2
2 1 0/4
Description
Transfers contents of memory at address indicated by Rm to DRn.
Operation
void FMOV_LOAD_DR (int m, int n) { DR[n >> 1] = Read_64 (R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH4 SH4A
fmov.d @Rm,XDn
(Rm) -> XDn
1111nnn1mmmm1000
LS LS
1 1
2 1
Description
Transfers contents of memory at address indicated by Rm to XDn.
Operation
void FMOV_LOAD_XD (int m, int n) { XD[n >> 1] = Read_64 (R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH4 SH4A SH2A
fmov.d DRm,@Rn
DRm -> (Rn)
1111nnnnmmm01010
LS LS
1 1 2
1 1 0
Description
Transfers DRm contents to memory at address indicated by Rn.
Operation
void FMOV_STORE_DR (int m, int n) { Write_64 (R[n], DR[m >> 1]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH4 SH4A
fmov.d XDm,@Rn
XDm -> (Rn)
1111nnnnmmm11010
LS LS
1 1
1 1
Description
Transfers contents of memory at address indicated by (R0 + Rm) to XDn.
Operation
void FMOV_STORE_XD (int m, int n) { Write_64 (R[n], XD[m >> 1]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH4 SH4A SH2A
fmov.d @Rm+,DRn
(Rm) -> DRn, Rm + 8 -> Rm
1111nnn0mmmm1001
LS LS
1 1 2
1/2 1 1/4
Description
Transfers contents of memory at address indicated by Rm to DRn, and adds 8 to Rm.
Operation
void FMOV_RESTORE_DR (int m, int n) { DR[n >> 1] = Read_64 (R[m]); R[m] += 8; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH4 SH4A
fmov.d @Rm+,XDn
(Rm) -> XDn, Rm+8 -> Rm
1111nnn1mmmm1001
LS LS
1 1
1/2 1
Description
Transfers contents of memory at address indicated by Rm to XDn, and adds 8 to Rm.
Operation
void FMOV_RESTORE_XD (int m, int n) { XD[n >> 1] = Read_64 (R[m]); R[m] += 8; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH4 SH4A SH2A
fmov.d DRm,@-Rn
Rn-8 -> Rn, DRm -> (Rn)
1111nnnnmmm01011
LS LS
1 1 2
1/1 1 0/1
Description
Subtracts 8 from Rn, and transfers DRm contents to memory at address indicated by resulting Rn value.
Operation
void FMOV_SAVE_DR (int m, int n) { Write_64 (R[n] - 8, DR[m >> 1]); R[n] -= 8; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH4 SH4A
fmov.d XDm,@-Rn
Rn-8 -> Rn, (Rn) -> XDm
1111nnnnmmm11011
LS LS
1 1
1/1 1
Description
Subtracts 8 from Rn, and transfers XDm contents to memory at address indicated by resulting Rn value.
Operation
void FMOV_SAVE_XD (int m, int n) { Write_64 (R[n] - 8, XD[m >> 1]); R[n] -= 8; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH4 SH4A SH2A
fmov.d @(R0,Rm),DRn
(R0 + Rm) -> DRn
1111nnn0mmmm0110
LS LS
1 1 2
2 1 0/4
Description
Transfers contents of memory at address indicated by (R0 + Rm) to DRn.
Operation
void FMOV_INDEX_LOAD_DR (int m, int n) { DR[n >> 1] = Read_64 (R[0] + R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH4 SH4A
fmov.d @(R0,Rm),XDn
(R0 + Rm) -> XDn
1111nnn1mmmm0110
LS LS
1 1
2 1
Description
Transfers contents of memory at address indicated by (R0 + Rm) to XDn.
Operation
void FMOV_INDEX_LOAD_XD (int m, int n) { XD[n >> 1] = Read_64 (R[0] + R[m]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH4 SH4A SH2A
fmov.d DRm,@(R0,Rn)
DRm -> (R0 + Rn)
1111nnnnmmm00111
LS LS
1 1 2
1 1 0
Description
Transfers DRm contents to memory at address indicated by (R0 + Rn).
Operation
void FMOV_INDEX_STORE_DR (int m, int n) { Write_64 (R[0] + R[n], DR[m >> 1]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH4 SH4A
fmov.d XDm,@(R0,Rn)
XDm -> (R0 + Rn)
1111nnnnmmm10111
LS LS
1 1
1 1
Description
Transfers XDm contents to memory at address indicated by (R0 + Rn).
Operation
void FMOV_INDEX_STORE_XD (int m, int n) { Write_64 (R[0] + R[n], XD[m >> 1]); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH2A
fmov.d @(disp12,Rm),DRn
(disp*8 + Rm) -> DRn
0011nnn0mmmm0001 0111dddddddddddd
2
0/4
Description
Transfers memory contents at the address indicated by (disp + Rn) to DRn.
Operation
void FMOV_INDEX_DISP12_LOAD_DR (int m, int n, int d) { long disp = (0x00000FFF & (long)d); DR[n >> 1] = Read_64 (R[m] + (disp << 3)); PC += 4; }
Possible Exceptions
- Data address error
SH2A
fmov.d DRm,@(disp12,Rn)
DRm -> (disp*8 + Rn)
0011nnnnmmm00001 0011dddddddddddd
2
0
Description
Transfers DRm contents to memory at the address indicated by (disp + Rn).
Operation
void FMOV_INDEX_DISP12_STORE_DR (int m, int n, int d) { long disp = (0x00000FFF & (long)d); Write_64 (R[n] + (disp << 3), DR[m >> 1]); PC += 4; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
Floating-Point Single-Precision Instructions (FPSCR.PR = 0)
SH2E SH3E SH4 SH4A SH2A
fldi0 FRn
0x00000000 -> FRn
1111nnnn10001101
LS LS
1 1 1 1 1
1 1 0 1 0
Description
When FPSCR.PR = 0, this instruction loads floating-point 0.0 (0x00000000) into FRn.
If FPSCR.PR = 1, the instruction is handled as an illegal instruction.
Operation
void FLDI0 (int n) { FR[n] = 0x00000000; PC += 2; }
SH2E SH3E SH4 SH4A SH2A
fldi1 FRn
0x3F800000 -> FRn
1111nnnn10011101
LS LS
1 1 1 1 1
1 1 0 1 0
Description
When FPSCR.PR = 0, this instruction loads floating-point 1.0 (0x3F800000) into FRn.
If FPCSR.PR = 1, the instruction is handled as an illegal instruction.
Operation
void FLDI1 (int n) { FR[n] = 0x3F800000; PC += 2; }
SH2E SH3E SH4 SH4A SH2A
flds FRm,FPUL
FRm -> FPUL
1111mmmm00011101
LS LS
1 1 1 1 1
1 1 0 1 0
Description
Transfers the contents of floating-point register FRm into system register FPUL.
Operation
void FLDS (int m) { FPUL = FR[m]; PC += 2; }
SH2E SH3E SH4 SH4A SH2A
fsts FPUL,FRn
FPUL -> FRn
1111nnnn00001101
LS LS
1 1 1 1 1
1 1 0 1 0
Description
Transfers the contents of system register FPUL to floating-point register FRn.
Operation
void FSTS (int n) { FR[n] = FPUL; PC += 2; }
SH2E SH3E SH4 SH4A SH2A
fabs FRn
FRn & 0x7FFFFFFF -> FRn
1111nnnn01011101
LS LS
1 1 1 1 1
1 1 0 1 0
Description
Clears the most significant bit of the contents of floating-point register FRn to 0, and stores the result in FRn.
Note
The cause and flag fields in FPSCR are not updated.
A double-precision floating-point register DRn consists of a single-precision floating-point register pair FRn:FRn+1, where FRn is the high part and FRn+1 is the low part. This instruction operates only on the high part and thus the operation performed for double and single precision setting is the same. It is not necessary to adjust the FPSRC.PR setting before this instruction.
Operation
void FABS (int n) { FR[n] = FR[n] & 0x7FFFFFFFF; PC += 2; }
SH2E SH3E SH4 SH4A SH2A
fneg FRn
FRn ^ 0x80000000 -> FRn
1111nnnn01001101
LS LS
1 1 1 1 1
1 1 0 1 0
Description
Inverts the most significant bit (sign bit) of the contents of floating-point register FRn, and stores the result in FRn.
Note
The cause and flag fields in FPSCR are not updated.
A double-precision floating-point register DRn consists of a single-precision floating-point register pair FRn:FRn+1, where FRn is the high part and FRn+1 is the low part. This instruction operates only on the high part and thus the operation performed for double and single precision setting is the same. It is not necessary to adjust the FPSRC.PR setting before this instruction.
Operation
void FNEG (int n) { FR[n] = -FR[n]; PC += 2; }
SH2E SH3E SH4 SH4A SH2A
fadd FRm,FRn
FRn + FRm -> FRn
1111nnnnmmmm0000
FE FE
1 1 1 1 1
1 1 3/4 1 3
Description
Arithmetically adds the two single-precision floating-point numbers in FRn and FRm, and stores the result in FRn.
When FPSCR.enable.I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When FPSCR.enable.O/U is set, FPU exception traps are generated on actual generation by the FPU exception source and on the satisfaction of certain special conditions that apply to this the instruction. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag and FRn is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Note
SH2E and SH3E support only invalid operation (V) and division by zero (Z) exception flags.
Operation
void FADD (int m, int n) { PC += 2; clear_cause ();
if (data_type_of (m) == sNaN || data_type_of (n) == sNaN) invalid (n); else if (data_type_of (m) == qNaN || data_type_of (n) == qNaN) qnan (n); else if (data_type_of (m) == DENORM || data_type_of (n) == DENORM) set_E (); else switch (data_type_of (m)) { case NORM: switch (data_type_of (n)) { case NORM: normal_faddsub (m, n, ADD); break; case PZERO: case NZERO: register_copy (m, n); break; default: break; } break;
case PZERO:
switch (data_type_of (n))
{
case NZERO:
zero (n, 0);
break;
default:
break;
}
break;
case NZERO:
break;
case PINF:
switch (data_type_of (n))
{
case NINF:
invalid (n);
break;
default:
inf (n, 0);
break;
}
break;
case NINF:
switch (data_type_of (n))
{
case PINF:
invalid (n);
break;
default:
inf (n, 1);
break;
}
break;
}
}
Possible Exceptions
- FPU Error
- Invalid Operation
- Overflow
Generation of overflow-exception traps
FRn and FRm have the same sign and the exponent of at least one value is 0xFE - Underflow
Generation of underflow-exception traps
FRn and FRm have different signs and neither has an exponent greater than 0x18 - Inexact
SH2E SH3E SH4 SH4A SH2A
fsub FRm,FRn
FRn - FRm -> FRn
1111nnnnmmmm0001
FE FE
1 1 1 1 1
1 1 3/4 1 3
Description
Arithmetically subtracts the single-precision floating-point number in FRm from the single-precision floating-point number in FRn, and stores the result in FRn.
When FPSCR.enable.I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When FPSCR.enable.O/U is set, FPU exception traps are generated on actual generation by the FPU exception source and on the satisfaction of certain special conditions that apply to this the instruction. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag and FRn is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Note
SH2E and SH3E support only invalid operation (V) and division by zero (Z) exception flags.
Operation
void FSUB (int m, int n) { PC += 2; clear_cause ();
if (data_type_of (m) == sNaN || data_type_of (n) == sNaN) invalid (n); else if (data_type_of (m) == qNaN || data_type_of (n) == qNaN) qnan (n); else if (data_type_of (m) == DENORM || data_type_of (n) == DENORM) set_E (); else switch (data_type_of (m)) { case NORM: switch (data_type_of (n)) { case NORM: normal_faddsub (m, n, SUB); break; case PZERO: case NZERO: register_copy (m, n); FR[n] = -FR[n]; break; default: break; } break;
case PZERO:
break;
case NZERO:
switch (data_type_of (n))
{
case NZERO:
zero (n, 0);
break;
default:
break;
}
break;
case PINF:
switch (data_type_of (n))
{
case PINF:
invalid (n);
break;
default:
inf (n, 1);
break;
}
break;
case NINF:
switch (data_type_of (n))
{
case NINF:
invalid (n);
break;
default:
inf (n, 0);
break;
}
break;
}
}
Possible Exceptions
- FPU Error
- Invalid Operation
- Overflow
Generation of overflow-exception traps
FRn and FRm have the same sign and the exponent of at least one value is 0xFE - Underflow
Generation of underflow-exception traps
FRn and FRm have different signs and neither has an exponent greater than 0x18 - Inexact
SH2E SH3E SH4 SH4A SH2A
fmul FRm,FRn
FRn * FRm -> FRn
1111nnnnmmmm0010
FE FE
1 1 1 1 1
1 1 3/4 1 3
Description
Arithmetically multiplies the two single-precision floating-point numbers in FRn and FRm, and stores the result in FRn.
When FPSCR.enable.I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When FPSCR.enable.O/U is set, FPU exception traps are generated on actual generation by the FPU exception source and on the satisfaction of certain special conditions that apply to this the instruction. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag and FRn is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Note
SH2E and SH3E support only invalid operation (V) and division by zero (Z) exception flags.
Operation
void FMUL (int m, int n) { PC += 2; clear_cause ();
if (data_type_of (m) == sNaN || data_type_of (n) == sNaN) invalid (n); else if (data_type_of (m) == qNaN || data_type_of (n) == qNaN) qnan (n); else if (data_type_of (m) == DENORM || data_type_of (n) == DENORM) set_E (); else switch (data_type_of (m)) { case NORM: switch (data_type_of (n)) { case PZERO: case NZERO: zero (n, sign_of (m) ^ sign_of (n)); break; case PINF: case NINF: inf (n, sign_of (m) ^ sign_of (n)); break; default: normal_fmul (m, n); break; } break;
case PZERO:
case NZERO:
switch (data_type_of (n))
{
case PINF:
case NINF:
invalid (n);
break;
default:
zero (n,sign_of (m) ^ sign_of (n));
break;
}
break;
case PINF:
case NINF:
switch (data_type_of (n))
{
case PZERO:
case NZERO:
invalid (n);
break;
default:
inf (n, sign_of (m) ^ sign_of (n));
break
}
break;
}
}
Possible Exceptions
- FPU Error
- Invalid Operation
- Overflow
Generation of overflow-exception traps
(exponent of FRn) + (exponent of FRm) - 0x7F is not less than 0xFE - Underflow
Generation of underflow-exception traps
When both FRn and FRm are normalized numbers: (exponent of FRn) + (exponent of FRm) - 0x7F is not more than 0x00
When at least FRn or FRm is not a normalized number: (exponent of FRn) + (exponent of FRm) - 0x7F is not more than 0x18 - Inexact
SH2E SH3E SH4 SH4A SH2A
fmac FR0,FRm,FRn
FR0 * FRm + FRn -> FRn
1111nnnnmmmm1110
FE FE
1 1 1 1 1
1 1 3/4 1 3
Description
Arithmetically multiplies the two single-precision floating-point numbers in FR0 and FRm, arithmetically adds the contents of FRn, and stores the result in FRn.
When FPSCR.enable.I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When FPSCR.enable.O/U is set, FPU exception traps are generated on actual generation by the FPU exception source and on the satisfaction of certain special conditions that apply to this the instruction. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag and FRn is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Note
SH2E and SH3E support only invalid operation (V) and division by zero (Z) exception flags.
This instruction rounds only the final result and does not round the intermediate result of the multiplication. Thus, for IEEE 754 compliant code, this instruction cannot be used as a replacement for individual FADD and FMUL instructions.
Operation
void FMAC (int m, int n) { PC += 2; clear_cause ();
if (FPSCR_PR == 1) undefined_operation ();
else if (data_type_of (0) == sNaN || data_type_of (m) == sNaN || data_type_of (n) == sNaN) invalid (n);
else if (data_type_of (0) == qNaN || data_type_of (m) == qNaN) qnan (n);
else if (data_type_of (0) == DENORM || data_type_of (m) == DENORM) set_E ();
else switch (data_type_of (0)) { case NORM: switch (data_type_of (m)) { case PZERO: case NZERO: switch (data_type_of (n)) { case DENORM: set_E (); break; case qNaN: qnan (n); break; case PZERO: case NZERO: zero (n, sign_of (0) ^ sign_of (m) ^ sign_of (n)); break; default: break; }
case PINF:
case NINF:
switch (data_type_of (n))
{
case DENORM:
set_E ();
break;
case qNaN:
qnan (n);
break;
case PINF:
case NINF:
if (sign_of (0) ^ sign_of (m) ^ sign_of (n))
invalid (n);
else
inf (n, sign_of (0) ^ sign_of (m));
break;
default:
inf (n, sign_of (0) ^ sign_of (m));
break;
}
case NORM:
switch (data_type_of (n))
{
case DENORM:
set_E ();
break;
case qNaN:
qnan (n);
break;
case PINF:
case NINF:
inf (n, sign_of (n));
break;
case PZERO:
case NZERO:
case NORM:
normal_fmac (m, n);
break;
}
break;
case PZERO:
case NZERO:
switch (data_type_of (m))
{
case PINF:
case NINF:
invalid (n);
break;
case PZERO:
case NZERO:
case NORM:
switch (data_type_of (n))
{
case DENORM:
set_E ();
break;
case qNaN:
qnan (n);
break;
case PZERO:
case NZERO:
zero (n, sign_of (0) ^ sign_of (m) ^ sign_of (n));
break;
default:
break;
}
break;
}
break;
case PINF:
case NINF:
switch (data_type_of (m))
{
case PZERO:
case NZERO:
invalid (n);
break;
default:
switch (data_type_of (n))
{
case DENORM:
set_E ();
break;
case qNaN:
qnan(n);
break;
default:
inf (n, sign_of (0) ^ sign_of (m) ^ sign_of (n));
break
}
break;
}
break;
}
}
}
void normal_fmac (int m, int n) { union { int double x; int l[4]; } dstx, tmpx;
float dstf, srcf;
if (data_type_of (n) == PZERO || data_type_of (n) == NZERO) srcf = 0.0; // flush denormalized value else srcf = FR[n];
tmpx.x = FR[0]; // convert single to int double tmpx.x *= FR[m]; //exact product dstx.x = tmpx.x + srcf;
if ((dstx.x == srcf && tmpx.x != 0.0) || (dstx.x == tmpx.x && srcf != 0.0)) { set_I (); if (sign_of (0) ^ sign_of (m) ^ sign_of (n)) { dstx.l[3] -= 1; // correct result if (dstx.l[3] == 0xFFFFFFFF) dstx.l[2] -= 1; if (dstx.l[2] == 0xFFFFFFFF) dstx.l[1] -= 1; if (dstx.l[1] == 0xFFFFFFFF) dstx.l[0] -= 1; } else dstx.l[3] |= 1 }
if ((dstx.l[1] & 0x01FFFFFF) || dstx.l[2] || dstx.l[3]) set_I();
if(FPSCR_RM == 1) { dstx.l[1] &= 0xFE000000; // round toward zero dstx.l[2] = 0x00000000; dstx.l[3] = 0x00000000; }
dstf = dstx.x; check_single_exception (&FR[n], dstf); }
Possible Exceptions
- FPU Error
- Invalid Operation
- Overflow
Generation of overflow-exception traps
At least one of the following results is not less than 0xFD:
(exponent of FR0) + (exponent of FRm)
(exponent of FRn) - Underflow
Generation of underflow-exception traps
At least one of the following results is not more than 0x2E:
(exponent of FR0) + (exponent of FRm)
(exponent of FRn) - Inexact
SH2E SH3E SH4 SH4A SH2A
fdiv FRm,FRn
FRn / FRm -> FRn
1111nnnnmmmm0011
FE FE
1 1 1 1 1
13 13 12/13 14 12
Description
Arithmetically divides the single-precision floating-point number in FRn by the single-precision floating-point number in FRm, and stores the result in FRn.
When FPSCR.enable.I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When FPSCR.enable.O/U is set, FPU exception traps are generated on actual generation by the FPU exception source and on the satisfaction of certain special conditions that apply to this the instruction. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag and FRn is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Note
SH2E and SH3E support only invalid operation (V) and division by zero (Z) exception flags.
Operation
void FDIV (int m, int n) { PC += 2; clear_cause ();
if (data_type_of (m) == sNaN || data_type_of (n) == sNaN) invalid (n); else if (data_type_of (m) == qNaN || data_type_of (n) == qNaN) qnan (n); else switch (data_type_of (m)) { case NORM: switch (data_type_of (n)) { case PINF: case NINF: inf (n, sign_of (m) ^ sign_of (n)); break; case PZERO: case NZERO: zero (n, sign_of (m) ^ sign_of (n)); break; case DENORM: set_E (); break; default: normal_fdiv_single (m, n); break; } break;
case PZERO:
switch (data_type_of (n))
{
case PZERO:
case NZERO:
invalid (n);
break;
case PINF:
case NINF:
break;
default:
dz (n, sign_of (m) ^ sign_of (n));
break;
}
break;
case NZERO:
switch (data_type_of (n))
{
case PZERO:
case NZERO:
invalid (n);
break;
case PINF:
inf (n, 1);
break;
case NINF:
inf (n, 0);
break;
default:
dz (FR[n], sign_of (m) ^ sign_of (n));
break;
}
break;
case DENORM:
set_E ();
break;
case PINF:
case NINF:
switch (data_type_of (n))
{
case DENORM:
set_E ();
break;
case PINF:
case NINF:
invalid (n);
break;
default:
zero (n, sign_of (m) ^ sign_of (n));
break;
}
break;
}
}
void normal_fdiv_single (int m, int n) { union { float f; int l; } dstf, tmpf;
union { double d; int l[2]; } tmpd;
tmpf.f = FR[n]; // save destination value dstf.f /= FR[m]; // round toward nearest or even tmpd.d = dstf.f; // convert single to double tmpd.d *= FR[m];
if (tmpf.f != tmpd.d) set_I (); if (tmpf.f < tmpd.d && FPSCR_RM == 1) dstf.l -= 1; // round toward zero
check_single_exception (&FR[n], dstf.f); }
Possible Exceptions
- FPU Error
- Invalid Operation
- Division by zero
- Overflow
Generation of overflow-exception traps
(exponent of FRn) - (exponent of FRm) + 0x7F is not less than 0xFF - Underflow
Generation of underflow-exception traps
(exponent of FRn) - (exponent of FRm) + 0x7F is not more than 0x01 - Inexact
SH3E SH4 SH4A SH2A
fsqrt FRn
sqrt (FRn) -> FRn
1111nnnn01101101
FE FE
1 1 1 1
13 11/12 30 11
Description
Finds the arithmetical square root of the single-precision floating-point number in FRn, and stores the result in FRn.
When FPSCR.enable.I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag and FRn is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Note
SH3E supports only invalid operation (V) and division by zero (Z) exception flags.
Operation
void FSQRT (int n) { PC += 2; clear_cause ();
switch (data_type_of (n)) { case NORM: if (sign_of (n) == 0) normal_fsqrt_single (n); else invalid (n); break;
case DENORM: if (sign_of (n) == 0) set_E (); else invalid (n); break;
case PZERO: case NZERO: case PINF: break;
case NINF: invalid (n); break;
case qNAN: qnan (n); break;
case sNAN: invalid (n); break; } }
void normal_fsqrt_single (int n) { union { float f; int l; } dstf, tmpf;
union { double d; int l[2]; } tmpd;
tmpf.f = FR[n]; // save destination value dstf.f = sqrt (FR[n]); // round toward nearest or even tmpd.d = dstf.f; // convert single to double tmpd.d *= dstf.f;
if (tmpf.f != tmpd.d) set_I (); if (tmpf.f < tmpd.d && FPSCR_RM == 1) dstf.l -= 1; // round toward zero if (FPSCR & ENABLE_I) fpu_exception_trap (); else FR[n] = dstf.f; }
Possible Exceptions
- FPU Error
- Invalid Operation
- Inexact
SH2E SH3E SH4 SH4A SH2A
fcmp/eq FRm,FRn
If FRn = FRm: 1 -> T Else: 0 -> T
1111nnnnmmmm0100
Result
FE FE
1 1 1 1 1
1 1 2/4 1 2
Description
Arithmetically compares the two single-precision floating-point numbers in FRn and FRm, and stores 1 in the T bit if they are equal, or 0 otherwise.
Operation result special cases
Operation
void FCMP_EQ (int m, int n) { PC += 2; clear_cause ();
if (fcmp_chk_single (m, n) == INVALID) fcmp_invalid (); else if (fcmp_chk_single (m, n) == EQ) T = 1; else T = 0; }
int fcmp_chk_single (int m, int n) { if (data_type_of (m) == sNaN || data_type_of (n) == sNaN) return INVALID; else if (data_type_of (m) == qNaN || data_type_of (n) == qNaN) return UO; else switch (data_type_of (m)) { case NORM: switch (data_type_of (n)) { case PINF: return GT; case NINF: return LT; default: break; } break;
case PZERO:
case NZERO:
switch (data_type_of (n))
{
case PZERO:
case NZERO:
return EQ;
default:
break;
}
break;
case PINF:
switch (data_type_of (n))
{
case PINF:
return EQ;
default:
return LT;
}
case NINF:
switch (data_type_of (n))
{
case NINF:
return EQ;
default:
return GT;
}
}
if (FR[n] == FR[m]) return EQ; else if (FR[n] > FR[m]) return GT; else return LT; }
void fcmp_invalid (void) { set_V ();
if ((FPSCR & ENABLE_V) == 0) T = 0; else fpu_exception_trap (); }
Possible Exceptions
- Invalid operation
SH2E SH3E SH4 SH4A SH2A
fcmp/gt FRm,FRn
If FRn > FRm: 1 -> T Else: 0 -> T
1111nnnnmmmm0101
Result
FE FE
1 1 1 1 1
1 1 2/4 1 2
Description
Arithmetically compares the two single-precision floating-point numbers in FRn and FRm, and stores 1 in the T bit if FRn > FRm, or 0 otherwise.
Operation result special cases
Note
For IEEE 754 conform less-than-or-equal comparison it is not sufficient to swap the operands. The FCMP/EQ must be used as well.
Operation
void FCMP_GT (int m, int n) { PC += 2; clear_cause ();
if (fcmp_chk_single (m, n) == INVALID || fcmp_chk_single (m, n) == UO) fcmp_invalid (); else if (fcmp_chk_single (m, n) == GT) T = 1; else T = 0; }
int fcmp_chk_single (int m, int n) { // see description of FCMP/EQ instruction. }
void fcmp_invalid (void) { // see description of FCMP/EQ instruction. }
Possible Exceptions
- Invalid operation
SH2E SH3E SH4 SH4A SH2A
float FPUL,FRn
(float)FPUL -> FRn
1111nnnn00101101
FE FE
1 1 1 1 1
1 1 3/4 1 3
Description
Taking the contents of FPUL as a 32-bit integer, converts this integer to a single-precision floating-point number and stores the result in FRn.
When FPSCR.enable.I = 1 an FPU exception trap is generated regardless of whether or not an exception has occurred. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag, and FRn is not updated. Appropriate processing should therefore be performed by software.
Note
SH2E and SH3E support only invalid operation (V) and division by zero (Z) exception flags.
Operation
void FLOAT_single (int n) { union { double d; int l[2]; } tmp;
PC += 2; clear_cause ();
FR[n] = FPUL; // convert from integer to float tmp.d = FPUL; if (tmp.l[1] & 0x1FFFFFFF) inexact(); }
Possible Exceptions
- Inexact
SH2E SH3E SH4 SH4A SH2A
ftrc FRm,FPUL
(long)FRm -> FPUL
1111mmmm00111101
FE FE
1 1 1 1 1
1 1 3/4 1 3
Description
Converts the single-precision floating-point number in FRm to a 32-bit integer, and stores the result in FPUL.
Operation result special cases
Note
The rounding mode is always truncation. The original SH4 has a pipeline exception. If the FTRC instruction is followed by an STS FPUL, Rn instruction, the latency of the FTRC instruction is reduced to 1 cycle.
Operation
#define NEG_INT_SINGLE_RANGE 0xCF000000 & 0x7FFFFFFF // -1.000000 * 2^31 #define POS_INT_SINGLE_RANGE 0x4EFFFFFF // 1.FFFFFE * 2^30
void FTRC_single (int m) { PC += 2; clear_cause ();
switch (ftrc_single_type_of (m)) { case NORM: FPUL = FR[m]; // Convert float to integer break; case PINF: ftrc_invalid (0, &FPUL); break; case NINF: ftrc_invalid (1, &FPUL); break; } }
int ftrc_single_type_of (int m) { if (sign_of (m) == 0) { if (FR_HEX[m] > 0x7F800000) return NINF; // NaN else if (FR_HEX[m] > POS_INT_SINGLE_RANGE) return PINF; // out of range, +INF else return NORM; // +0, +NORM } else { if ((FR_HEX[m] & 0x7FFFFFFF) > NEG_INT_SINGLE_RANGE) return NINF; // out of range, +INF, NaN else return NORM; // -0, -NORM } }
void ftrc_invalid (int sign, int* result) { set_V ();
if ((FPSCR & ENABLE_V) == 0) { if (sign == 0) *result = 0x7FFFFFFF; else *result = 0x80000000; } else fpu_exception_trap (); }
Possible Exceptions
- Invalid operation
SH4 SH4A
fipr FVm,FVn
inner_product (FVm, FVn) -> FR[n+3]
1111nnmm11101101
FE FE
1 1
4/5 1
Description
Calculates the inner products of the 4-dimensional single-precision floating-point vector indicated by FVn and FVm, and stores the results in FR[n + 3].
The FIPR instruction is intended for speed rather than accuracy, and therefore the results will differ from those obtained by using a combination of FADD and FMUL instructions. The FIPR execution sequence is as follows:
- Multiplies all terms. The results are 28 bits long.
- Aligns these results, rounding them to fit within 30 bits.
- Adds the aligned values.
- Performs normalization and rounding.
Special processing is performed in the following cases:
- If an input value is an sNaN, an invalid exception is generated.
- If the input values to be multiplied include a combination of 0 and infinity, an invalid exception is generated.
- In cases other than the above, if the input values include a qNaN, the result will be a qNaN.
- In cases other than the above, if the input values include infinity:
- If multiplication results in two or more infinities and the signs are different, an invalid exception will be generated.
- Otherwise, correct infinities will be stored.
- If the input values do not include an sNaN, qNaN, or infinity, processing is performed in the normal way.
When FPSCR.enable.U/I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When FPSCR.enable.O is set, FPU exception traps are generated on actual generation by the FPU exception source and on the satisfaction of certain special conditions that apply to this the instruction. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag, and FR[n+3] is not updated. Appropriate processing should therefore be performed by software.
Note
FV0 = { FR0, FR1, FR2, FR3 }
FV4 = { FR4, FR5, FR6, FR7 }
FV8 = { FR8, FR9, FR10, FR11 }
FV12 = { FR12, FR13, FR14, FR15 }
Operation
void FIPR (int m, int n) { if (FPSCR_PR == 0) { PC += 2; clear_cause (); fipr (m,n); } else undefined_operation (); }
Possible Exceptions
- Invalid operation
- Overflow
Generation of overflow exception traps
At least one of the following results is not less than 0xFC
(exponent of FRn) + (exponent of FRm)
(exponent of FR(n + 1)) + (exponent of FR(m + 1))
(exponent of FR(n + 2)) + (exponent of FR(m + 2))
(exponent of FR(n + 3)) + (exponent of FR(m + 3)) - Underflow
- Inexact
SH4 SH4A
ftrv XMTRX,FVn
transform_vector (XMTRX, FVn) -> FVn
1111nn0111111101
FE FE
1 1
5/8 4
Description
Takes the contents of floating-point registers XF0 to XF15 indicated by XMTRX as a 4-row × 4-column matrix, takes the contents of floating-point registers FR[n] to FR[n + 3] indicated by FVn as a 4-dimensional vector, multiplies the array by the vector, and stores the results in FV[n].
The FTRV instruction is intended for speed rather than accuracy, and therefore the results will differ from those obtained by using a combination of FADD and FMUL instructions. The FTRV execution sequence is as follows:
- Multiplies all terms. The results are 28 bits long.
- Aligns these results, rounding them to fit within 30 bits.
- Adds the aligned values.
- Performs normalization and rounding.
Special processing is performed in the following cases:
- If an input value is an sNaN, an invalid exception is generated.
- If the input values to be multiplied include a combination of 0 and infinity, an invalid operation exception is generated.
- In cases other than the above, if the input values include a qNaN, the result will be a qNaN.
- In cases other than the above, if the input values include infinity:
- If multiplication results in two or more infinities and the signs are different, an invalid exception will be generated.
- Otherwise, correct infinities will be stored.
- If the input values do not include an sNaN, qNaN, or infinity, processing is performed in the normal way.
When FPSCR.enable.V/O/U/I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag, and FVn is not updated. Appropriate processing should therefore be performed by software.
Note
A 4-dimensional matrix × matrix transformation can be realized by four FTRV instructions, where every FTRV calculates a column of the result matrix. The resulting matrix can be set to the XMTRX registers by toggling the FPSCR.FR bit to switch register banks without copying them.
Operation
void FTRV (int n) { if (FPSCR_PR != 0) undefined_operation (); else { float saved_vec[4]; float result_vec[4]; int saved_fpscr; int dst;
PC += 2;
clear_cause ();
saved_fpscr = FPSCR;
FPSCR &= ~ENABLE_VOUI; // mask VOUI enable
dst = 12 - n; // select other vector than FVn
for (int i = 0; i < 4; i++)
saved_vec[i] = FR[dst+i];
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
FR[dst+j] = XF[i+4j];
fipr (n, dst);
saved_fpscr |= FPSCR & (CAUSE | FLAG);
result_vec[i] = FR[dst+3];
}
for (int i = 0; i < 4; i++)
FR[dst+i] = saved_vec[i];
FPSCR = saved_fpscr;
if (FPSCR & ENABLE_VOUI)
fpu_exception_trap();
else
for (int i = 0; i < 4; i++)
FR[n+i] = result_vec[i];
} }
Possible Exceptions
- Invalid operation
- Overflow
- Underflow
- Inexact
SH4A
fsrra FRn
1.0 / sqrt (FRn) -> FRn
1111nnnn01111101
FE
1
1
Description
Takes the approximate inverse of the arithmetic square root (absolute error is within ±2-21) of the single-precision floating-point in FRn and writes the result to FRn. Since the this instruction operates by approximation, an imprecision exception is required when the input is a normalized value. In other cases, the instruction does not require an imprecision exception.
When FPSCR.enable.I is set, an FPU exception trap is generated. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag, and FRn is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Note
This instruction is also supported by the SH4 variant SH7091. Other SH4 variants such as SH7751, SH7760, SH7761 might also support it.
Operation
void FSRRA (int n) { if (FPSCR_PR != 0) undefined_operation (); else { PC += 2; clear_cause();
switch (data_type_of (n))
{
case NORM:
if (sign_of (n) == 0)
{
set_I ();
FR[n] = 1 / sqrt (FR[n]);
}
else
invalid (n);
break;
case DENORM:
if (sign_of (n) == 0)
fpu_error ();
else
invalid (n);
break;
case PZERO:
case NZERO:
dz (n, sign_of (n));
break;
case PINF:
FR[n] = 0;
break;
case NINF:
invalid (n);
break;
case qNAN:
qnan (n);
break;
case sNAN:
invalid (n);
break;
}
} }
Possible Exceptions
- FPU error
- Invalid operation
- Division by zero
- Inexact
SH4A
fsca FPUL,DRn
sin (FPUL) -> FRn cos (FPUL) -> FR[n+1]
1111nnn011111101
FE
1
3
Description
Calculates the sine and cosine approximations of FPUL (absolute error is within ±2-21) as single-precision floating point values, and places the values of the sine and cosine in FRn and FR[n + 1], respectively. Since this instruction is an approximate operation instruction, an imprecision exception is always required (even if the input is a 0, the result is imprecise).
The input angle is specified as a signed fraction in twos complement. The result of sin and cos is a single-precision floating-point number.
0x7FFFFFFF to 0x00000001: 360×215−360/216 to 360/216 degrees
0x00000000: 0 degree
0xFFFFFFFF to 0x80000000: −360/216 to −360×215 degrees
Note
This instruction is also supported by the SH4 variant SH7091. Other SH4 variants such as SH7751, SH7760, SH7761 might also support it.
Operation
void FSCA (int n) { if (FPSCR_PR != 0) undefined_operation (); else { float angle; long offset = 0x00010000; long fraction = 0x0000FFFF;
set_I ();
fraction &= FPUL; // extract sub-rotation (fraction) part
angle = fraction; // convert to float
angle = 2 * M_PI * angle / offset; // convert to radian
FR[n] = sin (angle);
FR[n+1] = cos (angle);
PC += 2;
} }
Possible Exceptions
- Inexact
Floating-Point Double-Precision Instructions (FPSCR.PR = 1)
SH4 SH4A SH2A
fabs DRn
DRn & 0x7FFFFFFFFFFFFFFF -> DRn
1111nnn001011101
LS LS
1 1 1
0 1 0
Description
Clears the most significant bit of the contents of floating-point register DRn to 0, and stores the result in DRn.
Note
The cause and flag fields in FPSCR are not updated.
A double-precision floating-point register DRn consists of a single-precision floating-point register pair FRn:FRn+1, where FRn is the high part and FRn+1 is the low part. This instruction operates only on the high part and thus the operation performed for double and single precision setting is the same. It is not necessary to adjust the FPSRC.PR setting before this instruction.
Operation
void FABS (int n) { FR[n] = FR[n] & 0x7FFFFFFFF; PC += 2; }
SH4 SH4A SH2A
fneg DRn
DRn ^ 0x8000000000000000 -> DRn
1111nnn001001101
LS LS
1 1 1
0 1 0
Description
Inverts the most significant bit (sign bit) of the contents of floating-point register DRn, and stores the result in DRn.
Note
The cause and flag fields in FPSCR are not updated.
A double-precision floating-point register DRn consists of a single-precision floating-point register pair FRn:FRn+1, where FRn is the high part and FRn+1 is the low part. This instruction operates only on the high part and thus the operation performed for double and single precision setting is the same. It is not necessary to adjust the FPSRC.PR setting before this instruction.
Operation
void FNEG (int n) { FR[n] = -FR[n]; PC += 2; }
SH4 SH4A SH2A
fadd DRm,DRn
DRn + DRm -> DRn
1111nnn0mmm00000
FE FE
1 1 1
7/9 1 0/8
Description
Arithmetically adds the two double-precision floating-point numbers in DRn and DRm, and stores the result in DRn.
When FPSCR.enable.I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When FPSCR.enable.O/U is set, FPU exception traps are generated on actual generation by the FPU exception source and on the satisfaction of certain special conditions that apply to this the instruction. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag and DRn is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Operation
void FADD (int m, int n) { PC += 2; clear_cause ();
if (data_type_of (m) == sNaN || data_type_of (n) == sNaN) invalid (n); else if (data_type_of (m) == qNaN || data_type_of (n) == qNaN) qnan (n); else if (data_type_of (m) == DENORM || data_type_of (n) == DENORM) set_E (); else switch (data_type_of (m)) { case NORM: switch (data_type_of (n)) { case NORM: normal_faddsub (m, n, ADD); break; case PZERO: case NZERO: register_copy (m, n); break; default: break; } break;
case PZERO:
switch (data_type_of (n))
{
case NZERO:
zero (n, 0);
break;
default:
break;
}
break;
case NZERO:
break;
case PINF:
switch (data_type_of (n))
{
case NINF:
invalid (n);
break;
default:
inf (n, 0);
break;
}
break;
case NINF:
switch (data_type_of (n))
{
case PINF:
invalid (n);
break;
default:
inf (n, 1);
break;
}
break;
}
}
Possible Exceptions
- FPU Error
- Invalid Operation
- Overflow
Generation of overflow-exception traps
DRn and DRm have the same sign and the exponent of at least one value is 0x7FE - Underflow
Generation of underflow-exception traps
DRn and DRm have different signs and neither has an exponent greater than 0x035 - Inexact
SH4 SH4A SH2A
fsub DRm,DRn
DRn - DRm -> DRn
1111nnn0mmm00001
FE FE
1 1 1
7/9 1 0/8
Description
Arithmetically subtracts the double-precision floating-point number in DRm from the double-precision floating-point number in DRn, and stores the result in DRn.
When FPSCR.enable.I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When FPSCR.enable.O/U is set, FPU exception traps are generated on actual generation by the FPU exception source and on the satisfaction of certain special conditions that apply to this the instruction. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag and DRn is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Operation
void FSUB (int m, int n) { PC += 2; clear_cause ();
if (data_type_of (m) == sNaN || data_type_of (n) == sNaN) invalid (n); else if (data_type_of (m) == qNaN || data_type_of (n) == qNaN) qnan (n); else if (data_type_of (m) == DENORM || data_type_of (n) == DENORM) set_E (); else switch (data_type_of (m)) { case NORM: switch (data_type_of (n)) { case NORM: normal_faddsub (m, n, SUB); break; case PZERO: case NZERO: register_copy (m, n); FR[n] = -FR[n]; break; default: break; } break;
case PZERO:
break;
case NZERO:
switch (data_type_of (n))
{
case NZERO:
zero (n, 0);
break;
default:
break;
}
break;
case PINF:
switch (data_type_of (n))
{
case PINF:
invalid (n);
break;
default:
inf (n, 1);
break;
}
break;
case NINF:
switch (data_type_of (n))
{
case NINF:
invalid (n);
break;
default:
inf (n, 0);
break;
}
break;
}
}
Possible Exceptions
- FPU Error
- Invalid Operation
- Overflow
Generation of overflow-exception traps
DRn and DRm have the same sign and the exponent of at least one value is 0x7FE - Underflow
Generation of underflow-exception traps
DRn and DRm have different signs and neither has an exponent greater than 0x035 - Inexact
SH4 SH4A SH2A
fmul DRm,DRn
DRn * DRm -> DRn
1111nnn0mmm00010
FE FE
1 1 1
7/9 3 0/8
Description
Arithmetically multiplies the two double-precision floating-point numbers in DRn and DRm, and stores the result in FRn.
When FPSCR.enable.I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When FPSCR.enable.O/U is set, FPU exception traps are generated on actual generation by the FPU exception source and on the satisfaction of certain special conditions that apply to this the instruction. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag and DRn is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Operation
void FMUL (int m, int n) { PC += 2; clear_cause ();
if (data_type_of (m) == sNaN || data_type_of (n) == sNaN) invalid (n); else if (data_type_of (m) == qNaN || data_type_of (n) == qNaN) qnan (n); else if (data_type_of (m) == DENORM || data_type_of (n) == DENORM) set_E (); else switch (data_type_of (m)) { case NORM: switch (data_type_of (n)) { case PZERO: case NZERO: zero (n, sign_of (m) ^ sign_of (n)); break; case PINF: case NINF: inf (n, sign_of (m) ^ sign_of (n)); break; default: normal_fmul (m, n); break; } break;
case PZERO:
case NZERO:
switch (data_type_of (n))
{
case PINF:
case NINF:
invalid (n);
break;
default:
zero (n,sign_of (m) ^ sign_of (n));
break;
}
break;
case PINF:
case NINF:
switch (data_type_of (n))
{
case PZERO:
case NZERO:
invalid (n);
break;
default:
inf (n, sign_of (m) ^ sign_of (n));
break
}
break;
}
}
Possible Exceptions
- FPU Error
- Invalid Operation
- Overflow
Generation of overflow-exception traps
(exponent of DRn) + (exponent of DRm) - 0x3FF is not less than 0x7FE - Underflow
Generation of underflow-exception traps
(exponent of DRn) + (exponent of DRm) - 0x3FF is not more than 0x000 - Inexact
SH4 SH4A SH2A
fdiv DRm,DRn
DRn / DRm -> DRn
1111nnn0mmm00011
FE FE
1 1 1
24/26 14 0/24
Description
Arithmetically divides the double-precision floating-point number in DRn by the double-precision floating-point number in DRm, and stores the result in DRn.
When FPSCR.enable.I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When FPSCR.enable.O/U is set, FPU exception traps are generated on actual generation by the FPU exception source and on the satisfaction of certain special conditions that apply to this the instruction. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag and DRn is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Operation
void FDIV (int m, int n) { PC += 2; clear_cause ();
if (data_type_of (m) == sNaN || data_type_of (n) == sNaN) invalid (n); else if (data_type_of (m) == qNaN || data_type_of (n) == qNaN) qnan (n); else switch (data_type_of (m)) { case NORM: switch (data_type_of (n)) { case PINF: case NINF: inf (n, sign_of (m) ^ sign_of (n)); break; case PZERO: case NZERO: zero (n, sign_of (m) ^ sign_of (n)); break; case DENORM: set_E (); break; default: normal_fdiv_double (m, n); break; } break;
case PZERO:
switch (data_type_of (n))
{
case PZERO:
case NZERO:
invalid (n);
break;
case PINF:
case NINF:
break;
default:
dz (n, sign_of (m) ^ sign_of (n));
break;
}
break;
case NZERO:
switch (data_type_of (n))
{
case PZERO:
case NZERO:
invalid (n);
break;
case PINF:
inf (n, 1);
break;
case NINF:
inf (n, 0);
break;
default:
dz (FR[n], sign_of (m) ^ sign_of (n));
break;
}
break;
case DENORM:
set_E ();
break;
case PINF:
case NINF:
switch (data_type_of (n))
{
case DENORM:
set_E ();
break;
case PINF:
case NINF:
invalid (n);
break;
default:
zero (n, sign_of (m) ^ sign_of (n));
break;
}
break;
}
}
void normal_fdiv_double (int m, int n) { union { double d; int l[2]; } dstd, tmpd;
union { int double x; int l[4]; } tmpx;
tmpd.d = DR[n >> 1]; // save destination value dstd.d /= DR[m >> 1]; // round toward nearest or even tmpx.x = dstd.d; // convert double to int double tmpx.x *= DR[m >> 1];
if (tmpd.d != tmpx.x) set_I (); if (tmpd.d < tmpx.x && FPSCR_RM == 1) { dstd.l[1] -= 1; // round toward zero if (dstd.l[1] == 0xFFFFFFFF) dstd.l[0] -= 1; }
check_double_exception (&DR[n >> 1], dstd.d); }
Possible Exceptions
- FPU Error
- Invalid Operation
- Division by zero
- Overflow
Generation of overflow-exception traps
(exponent of DRn) - (exponent of DRm) + 0x3FF is not less than 0x7FF - Underflow
Generation of underflow-exception traps
(exponent of DRn) - (exponent of DRm) + 0x3FF is not more than 0x001 - Inexact
SH4 SH4A SH2A
fsqrt DRn
sqrt (DRn) -> DRn
1111nnn001101101
FE FE
1 1 1
23/25 30 0/24
Description
Finds the arithmetical square root of the double-precision floating-point number in DRn, and stores the result in DRn.
When FPSCR.enable.I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag and DRn is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Operation
void FSQRT (int n) { PC += 2; clear_cause ();
switch (data_type_of (n)) { case NORM: if (sign_of (n) == 0) normal_fsqrt_double (n); else invalid (n); break;
case DENORM: if (sign_of (n) == 0) set_E (); else invalid (n); break;
case PZERO: case NZERO: case PINF: break;
case NINF: invalid (n); break;
case qNAN: qnan (n); break;
case sNAN: invalid (n); break; } }
void normal_fsqrt_double (int n) { union { double d; int l[2]; } dstd, tmpd;
union { int double x; int l[4]; } tmpx;
tmpd.d = DR[n >> 1]; // save destination value dstd.d = sqrt (DR[n >> 1]); // round toward nearest or even tmpx.x = dstd.d; // convert double to int double tmpx.x *= dstd.d;
if (tmpd.d != tmpx.x) set_I (); if (tmpd.d < tmpx.x && FPSCR_RM == 1) { dstd.l[1] -= 1; // round toward zero if (dstd.l[1] == 0xFFFFFFFF) dstd.l[0] -= 1; } if (FPSCR & ENABLE_I) fpu_exception_trap(); else DR[n >> 1] = dstd.d; }
Possible Exceptions
- FPU Error
- Invalid Operation
- Inexact
SH4 SH4A SH2A
fcmp/eq DRm,DRn
If DRn = DRm: 1 -> T Else: 0 -> T
1111nnn0mmm00100
Result
CO FE
2 1 2
3/5 1 3
Description
Arithmetically compares the two double-precision floating-point numbers in DRn and DRm, and stores 1 in the T bit if they are equal, or 0 otherwise.
Operation result special cases
Operation
void FCMP_EQ (int m, int n) { PC += 2; clear_cause ();
if (fcmp_chk_double (m, n) == INVALID) fcmp_invalid (); else if (fcmp_chk_double (m, n) == EQ) T = 1; else T = 0; }
int fcmp_chk_double (int m, int n) { if (data_type_of (m) == sNaN || data_type_of (n) == sNaN) return INVALID; else if (data_type_of (m) == qNaN || data_type_of (n) == qNaN) return UO; else switch (data_type_of (m)) { case NORM: switch (data_type_of (n)) { case PINF: return GT; case NINF: return LT; default: break; } break;
case PZERO:
case NZERO:
switch (data_type_of (n))
{
case PZERO:
case NZERO:
return EQ;
default:
break;
}
break;
case PINF:
switch (data_type_of (n))
{
case PINF:
return EQ;
default:
return LT;
}
case NINF:
switch (data_type_of (n))
{
case NINF:
return EQ;
default:
return GT;
}
}
if (DR[n >> 1] == DR[m >> 1]) return EQ; else if (DR[n >> 1] > DR[m >> 1]) return GT; else return LT; }
void fcmp_invalid (void) { set_V ();
if ((FPSCR & ENABLE_V) == 0) T = 0; else fpu_exception_trap (); }
Possible Exceptions
- Invalid operation
SH4 SH4A SH2A
fcmp/gt DRm,DRn
If DRn > DRm: 1 -> T Else: 0 -> T
1111nnn0mmm00101
Result
CO FE
2 1 2
3/5 1 3
Description
Arithmetically compares the two double-precision floating-point numbers in DRn and DRm, and stores 1 in the T bit if DRn > DRm, or 0 otherwise.
Operation result special cases
Note
For IEEE 754 conform less-than-or-equal comparison it is not sufficient to swap the operands. The FCMP/EQ must be used as well.
Operation
void FCMP_GT (int m, int n) { PC += 2; clear_cause ();
if (fcmp_chk_double (m, n) == INVALID || fcmp_chk_double (m, n) == UO) fcmp_invalid (); else if (fcmp_chk_double (m, n) == GT) T = 1; else T = 0; }
int fcmp_chk_double (int m, int n) { // see description of FCMP/EQ instruction. }
void fcmp_invalid (void) { // see description of FCMP/EQ instruction. }
Possible Exceptions
- Invalid operation
SH4 SH4A SH2A
float FPUL,DRn
(double)FPUL -> DRn
1111nnn000101101
FE FE
1 1 1
3/5 1 0/4
Description
Taking the contents of FPUL as a 32-bit integer, converts this integer to a double-precision floating-point number and stores the result in DRn.
Operation
void FLOAT_double (int n) { union { double d; int l[2]; } tmp;
PC += 2; clear_cause ();
DR[n >> 1] = FPUL; // convert from integer to double }
SH4 SH4A SH2A
ftrc DRm,FPUL
(long)DRm -> FPUL
1111mmm000111101
FE FE
1 1 1
4/5 1 0/4
Description
Converts the double-precision floating-point number in DRm to a 32-bit integer, and stores the result in FPUL.
Operation result special cases
Note
The rounding mode is always truncation.
Operation
#define NEG_INT_DOUBLE_RANGE 0xC1E0000000200000 & 0x7FFFFFFFFFFFFFFF #define POS_INT_DOUBLE_RANGE 0x41E0000000000000
void FTRC_double (int m) { PC += 2; clear_cause ();
switch (ftrc_double_type_of (m)) { case NORM: FPUL = DR[m >> 1]; // Convert double to integer break; case PINF: ftrc_invalid (0, &FPUL); break; case NINF: ftrc_invalid (1, &FPUL); break; } }
int ftrc_double_type_of (int m) { if (sign_of (m) == 0) { if (FR_HEX[m] > 0x7FF00000 || (FR_HEX[m] == 0x7FF00000 && FR_HEX[m+1] != 0x00000000)) return NINF; // NaN else if (DR_HEX[m >> 1] >= POS_INT_DOUBLE_RANGE) return PINF; // out of range, +INF else return NORM; // +0, +NORM } else { if ((DR_HEX[m >> 1] & 0x7FFFFFFFFFFFFFFF) >= NEG_INT_DOUBLE_RANGE) return NINF; // out of range, +INF, NaN else return NORM; // -0, -NORM } }
void ftrc_invalid (int sign, int* result) { set_V ();
if ((FPSCR & ENABLE_V) == 0) { if (sign == 0) *result = 0x7FFFFFFF; else *result = 0x80000000; } else fpu_exception_trap (); }
Possible Exceptions
- Invalid operation
SH4 SH4A SH2A
fcnvds DRm,FPUL
double_to_float (DRm) -> FPUL
1111mmm010111101
FE FE
1 1 1
4/5 1 4
Description
Converts the double-precision floating-point number in DRm to a single-precision floating-point number, and stores the result in FPUL.
When FPSCR.enable. I is set, an FPU exception trap is generated regardless of whether or not an exception has occurred. When FPSCR.enable.O/U is set, FPU exception traps are generated on actual generation by the FPU exception source and on the satisfaction of certain special conditions that apply to this the instruction. When an exception occurs, correct exception information is reflected in FPSCR.cause and FPSCR.flag, and FPUL is not updated. Appropriate processing should therefore be performed by software.
Operation result special cases
Operation
void FCNVDS (int m) { if (FPSCR_PR != 1) undefined_operation (); else { PC += 2; clear_cause ();
switch (data_type_of (m))
{
case NORM:
case PZERO:
case NZERO:
normal_fcnvds (m, &FPUL);
break;
case DENORM:
set_E ();
case PINF:
FPUL = 0x7F800000;
break;
case NINF:
FPUL = 0xFF800000;
break;
case qNaN:
FPUL = 0x7FBFFFFF;
break;
case sNaN:
set_V ();
if ((FPSCR & ENABLE_V) == 0)
FPUL = 0x7FBFFFFF;
else
fpu_exception_trap ();
break;
}
} }
void normal_fcnvds (int m, float* result) { int sign; float abs;
union { float f; int l; } dstf, tmpf;
union { double d; int l[2]; } dstd;
dstd.d = DR [m >> 1];
if (dstd.l[1] & 0x1FFFFFFF)) set_I ();
if (FPSCR_RM == 1) dstd.l[1] &= 0xE0000000; // round toward zero
dstf.f = dstd.d; check_single_exception (result, dstf.f); }
Possible Exceptions
- FPU error
- Invalid operation
- Overflow
Generation of overflow exception traps
The exponent of DRn is not less than 0x47E - Underflow
Generation of underflow exception traps
The exponent of DRn is not more than 0x380 - Inexact
SH4 SH4A SH2A
fcnvsd FPUL,DRn
float_to_double (FPUL) -> DRn
1111nnn010101101
FE FE
1 1 1
3/5 1 4
Description
Converts the single-precision floating-point number in FPUL to a double-precision floating-point number, and stores the result in DRn.
Operation result special cases
Operation
void FCNVSD (int n) { if (FPSCR_PR != 1) undefined_operation (); else { switch (fpul_type ()) { case PZERO: case NZERO: case PINF: case NINF: case NORM: DR[n >> 1] = FPUL; // convert float to double break;
case DENORM:
set_E ();
break;
case qNaN:
qnan (n);
break;
case sNaN:
invalid (n);
break;
}
} }
int fpul_type () { int abs = FPUL & 0x7FFFFFFF; if (abs < 0x00800000) { if (FPSCR_DN == 1 || abs == 0x00000000) { if (sign_of (FPUL) == 0) return PZERO; else return NZERO; } else return DENORM; } else if (abs < 0x7F800000) return NORM; else if (abs == 0x7F800000) { if (sign_of (FPUL) == 0) return PINF; else return NINF; } else if (abs < 0x7FC00000) return qNaN; else return sNaN; }
Possible Exceptions
- FPU error
- Invalid operation
Floating-Point Control Instructions
SH2E SH3E SH4 SH4A SH2A
lds Rm,FPSCR
Rm -> FPSCR
0100mmmm01101010
CO LS
1 1 1 1 1
1 1 4 1 3
Description
Loads the source operand into FPU system register FPSCR.
Operation
void LDSFPSCR (int m) { #if SH2E || SH3E FPSCR = R[m] & 0x00018C60;
#elif SH4 || SH4A || SH2A FPSCR = R[m] & 0x003FFFFF;
#endif
PC += 2; }
SH2E SH3E SH4 SH4A SH2A
sts FPSCR,Rn
FPSCR -> Rn
0000nnnn01101010
CO LS
1 1 1 1 1
1 1 3 1 2
Description
Stores FPU system register FPSCR in the destination.
Operation
void STSFPSCR (int n) { #if SH2E || SH3E R[n] = FPSCR;
#elif SH4 || SH4A || SH2A R[n] = FPSCR & 0x003FFFFF;
#endif
PC += 2; }
SH2E SH3E SH4 SH4A SH2A
lds.l @Rm+,FPSCR
(Rm) -> FPSCR, Rm+4 -> Rm
0100mmmm01100110
CO LS
1 1 1 1 1
1 1 3 1 3
Description
Loads the source operand into FPU system register FPSCR.
Operation
void LDSMFPSCR (int m) { #if SH2E || SH3E FPSCR = Read_32 (R[m]) & 0x00018C60;
#elif SH4 || SH4A || SH2A FPSCR = Read_32 (R[m]) & 0x003FFFFF;
#endif
R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH2E SH3E SH4 SH4A SH2A
sts.l FPSCR,@-Rn
Rn-4 -> Rn, FPSCR -> (Rn)
0100nnnn01100010
CO LS
1 1 1 1 1
1 1 1/1 1 1
Description
Stores FPU system register FPSCR in the destination.
Operation
void STSMFPSCR (int n) { R[n] -= 4;
#if SH2E || SH3E Write_32 (R[n], FPSCR);
#elif SH4 || SH4A || SH2A Write_32 (R[n], FPSCR & 0x003FFFFF);
#endif
PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH2E SH3E SH4 SH4A SH2A
lds Rm,FPUL
Rm -> FPUL
0100mmmm01011010
LS LS
1 1 1 1 1
1 1 1 1 1
Description
Loads the source operand into FPU system register FPUL.
Operation
void LDSFPUL (int m) { FPUL = R[m]; PC += 2; }
SH2E SH3E SH4 SH4A SH2A
sts FPUL,Rn
FPUL -> Rn
0000nnnn01011010
LS LS
1 1 1 1 1
1 1 3 1 2
Description
Stores FPU system register FPUL in the destination.
Note
The original SH4 has a pipeline exception. If the FTRC instruction is followed by an STS FPUL, Rn instruction, the latency of the FTRC instruction is reduced to 1 cycle.
Operation
void STSFPUL (int n) { R[n] = FPUL; PC += 2; }
SH2E SH3E SH4 SH4A SH2A
lds.l @Rm+,FPUL
(Rm) -> FPUL, Rm+4 -> Rm
0100mmmm01010110
LS LS
1 1 1 1 1
1 1 1/2 1 2
Operation
void LDSMFPUL (int m) { FPUL = Read_32 (R[m]); R[m] += 4; PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
SH2E SH3E SH4 SH4A SH2A
sts.l FPUL,@-Rn
Rn-4 -> Rn, FPUL -> (Rn)
0100nnnn01010010
CO LS
1 1 1 1 1
1 1 1/1 1 2
Description
Stores FPU system register FPUL in the destination.
Operation
void STSMFPUL (int n) { R[n] -= 4; Write_32 (R[n], FPUL); PC += 2; }
Possible Exceptions
- Data TLB multiple-hit exception
- Data TLB miss exception
- Data TLB protection violation exception
- Data address error
- Initial page write exception
SH4 SH4A
frchg
If FPSCR.PR = 0: ~FPSCR.FR -> FPSCR.FR Else: Undefined Operation
1111101111111101
FE FE
1 1
1/4 1
Description
Inverts the FR bit in floating-point register FPSCR. When the FR bit in FPSCR is changed, FR0 to FR15 in FPR0_BANK0 to FPR15_BANK0 and FPR0_BANK1 to FPR15_BANK1 become XR0 to XR15, and XR0 to XR15 become FR0 to FR15. When FPSCR.FR = 0, FPR0_BANK0 to FPR15_BANK0 correspond to FR0 to FR15, and FPR0_BANK1 to FPR15_BANK1 correspond to XR0 to XR15. When FPSCR.FR = 1, FPR0_BANK1 to FPR15_BANK1 correspond to FR0 to FR15, and FPR0_BANK0 to FPR15_BANK0 correspond to XR0 to XR15.
Operation
void FRCHG (void) { if (FPSCR_PR == 0) { FPSCR ^= 0x00200000; // toggle bit 21 PC += 2; } else undefined_operation (); }
SH4 SH4A SH2A
fschg
If FPSCR.PR = 0: ~FPSCR.SZ -> FPSCR.SZ Else: Undefined Operation
1111001111111101
FE FE
1 1 1
1/4 1 1
Description
Inverts the SZ bit of the floating-point status register FPSCR. Changing the value of the SZ bit in FPSCR switches the amount of data for transfer by the FMOV instruction between one single-precision data and a pair of single-precision data. When FPSCR.SZ = 0, an FMOV instruction transfers a single-precision number. When FPSCR.SZ = 1, the FMOV instruction transfers a pair of single-precision numbers.
Operation
void FSCHG (void) { if (FPSCR_PR == 0) { FPSCR ^= 0x00100000; // toggle bit 20 PC += 2; } else undefined_operation (); }
SH4A
fpchg
~FPSCR.PR -> FPSCR.PR
1111011111111101
FE
1
1
Description
Inverts the PR bit of the floating-point status register FPSCR. The value of this bit selects single-precision or double-precision operation.
Operation
void FPCHG (void) { FPSCR ^= 0x00080000; // toggle bit 19 PC += 2; }
DSP Data Transfer Instructions
DSP
nopx
No operation
1111000*0*0*00**
1
1
Description
No access operation for X memory.
DSP
movx.w @Ax,Dx
(Ax) -> MSW of Dx, 0 -> LSW of Dx
111100A*D*0*01**
1
1
Description
Transfers the memory source operand data to the destination register operand. The transferred data can only be word length for X memory. The word data is loaded to the top word of the register and the bottom word is cleared with zeros.
Note
"*" of the instruction code is MOVY instruction designation area.
MSW = High-order word of operand.
LSW = Low-order word of operand.
Example
MOVX.W @R4,X0 ! Before execution: R4 = 0x08010000, @R4 = 0x5555, X0 = 0x12345678 ! After execution: R4 = 0x08010000, X0 = 0x55550000
DSP
movx.w @Ax+,Dx
(Ax) -> MSW of Dx, 0 -> LSW of Dx, Ax+2 -> Ax
111100A*D*0*10**
1
1
Description
Transfers the memory source operand data to the destination register operand. The transferred data can only be word length for X memory. The word data is loaded to the top word of the register and the bottom word is cleared with zeros.
Note
"*" of the instruction code is MOVY instruction designation area.
MSW = High-order word of operand.
LSW = Low-order word of operand.
Example
MOVX.W @R4+,X0 ! Before execution: R4 = 0x08010000, @R4 = 0x5555, X0 = 0x12345678 ! After execution: R4 = 0x08010002, X0 = 0x55550000
DSP
movx.w @Ax+Ix,Dx
(Ax) -> MSW of Dx, 0 -> LSW of Dx, Ax+Ix -> Ax
111100A*D*0*11**
1
1
Description
Transfers the memory source operand data to the destination register operand. The transferred data can only be word length for X memory. The word data is loaded to the top word of the register and the bottom word is cleared with zeros.
Note
"*" of the instruction code is MOVY instruction designation area.
MSW = High-order word of operand.
LSW = Low-order word of operand.
DSP
movx.w Da,@Ax
MSW of Da -> (Ax)
111100A*D*1*01**
1
1
Description
Transfers the register source operand data to the destination memory operand. The transferred data can only be word length for X memory. The source word data is the top word of the register.
Note
"*" of the instruction code is MOVY instruction designation area.
MSW = High-order word of operand.
DSP
movx.w Da,@Ax+
MSW of Da -> (Ax), Ax+2 -> Ax
111100A*D*1*10**
1
1
Description
Transfers the register source operand data to the destination memory operand. The transferred data can only be word length for X memory. The source word data is the top word of the register.
Note
"*" of the instruction code is MOVY instruction designation area.
MSW = High-order word of operand.
DSP
movx.w Da,@Ax+Ix
MSW of Da -> (Ax), Ax+Ix -> Ax
111100A*D*1*11**
1
1
Description
Transfers the register source operand data to the destination memory operand. The transferred data can only be word length for X memory. The source word data is the top word of the register.
Note
"*" of the instruction code is MOVY instruction designation area.
MSW = High-order word of operand.
DSP
nopy
No Operation
111100*0*0*0**00
1
1
Description
No access operation for Y memory.
DSP
movy.w @Ay,Dy
(Ay) -> MSW of Dy, 0 -> LSW of Dy
111100*A*D*0**01
1
1
Description
Transfers the memory source operand data to the destination register operand. The transferred data can only be word length for Y memory. The word data is loaded to the top word of the register and the bottom word is cleared with zeros.
Note
"*" of the instruction code is MOVX instruction designation area.
MSW = High-order word of operand.
LSW = Low-order word of operand.
DSP
movy.w @Ay+,Dy
(Ay) -> MSW of Dy, 0 -> LSW of Dy, Ay+2 -> Ay
111100*A*D*0**10
1
1
Description
Transfers the memory source operand data to the destination register operand. The transferred data can only be word length for Y memory. The word data is loaded to the top word of the register and the bottom word is cleared with zeros.
Note
"*" of the instruction code is MOVX instruction designation area.
MSW = High-order word of operand.
LSW = Low-order word of operand.
DSP
movy.w @Ay+Iy,Dy
(Ay) -> MSW of Dy, 0 -> LSW of Dy, Ay+Iy -> Ay
111100*A*D*0**11
1
1
Description
Transfers the memory source operand data to the destination register operand. The transferred data can only be word length for Y memory. The word data is loaded to the top word of the register and the bottom word is cleared with zeros.
Note
"*" of the instruction code is MOVX instruction designation area.
MSW = High-order word of operand.
LSW = Low-order word of operand.
DSP
movy.w Da,@Ay
MSW of Da -> (Ay)
111100*A*D*1**01
1
1
Description
Transfers the register source operand data to the destination memory operand. The transferred data can only be word length for Y memory. The source word data is the top word of the register.
Note
"*" of the instruction code is MOVX instruction designation area.
MSW = High-order word of operand.
DSP
movy.w Da,@Ay+
MSW of Da -> (Ay), Ay+2 -> Ay
111100*A*D*1**10
1
1
Description
Transfers the register source operand data to the destination memory operand. The transferred data can only be word length for Y memory. The source word data is the top word of the register.
Note
"*" of the instruction code is MOVX instruction designation area.
MSW = High-order word of operand.
DSP
movy.w Da,@Ay+Iy
MSW of Da -> (Ay), Ay+Iy -> Ay
111100*A*D*1**11
1
1
Description
Transfers the register source operand data to the destination memory operand. The transferred data can only be word length for Y memory. The source word data is the top word of the register.
Note
"*" of the instruction code is MOVX instruction designation area.
MSW = High-order word of operand.
DSP
movs.w @-As,Ds
As-2 -> As, (As) -> MSW of Ds, 0 -> LSW of Ds
111101AADDDD0000
1
1
Description
Transfers the source operand data to the destination. The transferred data is a word, the word data is loaded to the top word of the register and the bottom word is cleared with zeros. When the destination operand is a register with guard bits, the sign is extended and stored in the guard bits.
DSP
movs.w @As,Ds
(As) -> MSW of Ds, 0 -> LSW of Ds
111101AADDDD0100
1
1
Description
Transfers the source operand data to the destination. The transferred data is a word, the word data is loaded to the top word of the register and the bottom word is cleared with zeros. When the destination operand is a register with guard bits, the sign is extended and stored in the guard bits.
DSP
movs.w @As+,Ds
(As) -> MSW of Ds, 0 -> LSW of Ds, As+2 -> As
111101AADDDD1000
1
1
Description
Transfers the source operand data to the destination. The transferred data is a word, the word data is loaded to the top word of the register and the bottom word is cleared with zeros. When the destination operand is a register with guard bits, the sign is extended and stored in the guard bits.
DSP
movs.w @As+Ix,Ds
(As) -> MSW of Ds, 0 -> LSW of DS, As+Ix -> As
111101AADDDD1100
1
1
Description
Transfers the source operand data to the destination. The transferred data is a word, the word data is loaded to the top word of the register and the bottom word is cleared with zeros. When the destination operand is a register with guard bits, the sign is extended and stored in the guard bits.
DSP
movs.w Ds,@-As
As-2 -> As, MSW of Ds -> (As)
111101AADDDD0001
1
1
Description
Transfers the source operand data to the destination. The transferred data is a word, the top word of the register is stored as the word data.
Note
When one of the guard bit registers A0G and A1G is the source operand it is sign extended and stored as a word.
DSP
movs.w Ds,@As
MSW of Ds -> (As)
111101AADDDD0101
1
1
Description
Transfers the source operand data to the destination. The transferred data is a word, the top word of the register is stored as the word data.
Note
When one of the guard bit registers A0G and A1G is the source operand it is sign extended and stored as a word.
DSP
movs.w Ds,@As+
MSW of Ds -> (As), As+2 -> As
111101AADDDD1001
1
1
Description
Transfers the source operand data to the destination. The transferred data is a word, the top word of the register is stored as the word data.
Note
When one of the guard bit registers A0G and A1G is the source operand it is sign extended and stored as a word.
DSP
movs.w Ds,@As+Is
MSW of DS -> (As), As+Is -> As
111101AADDDD1101
1
1
Description
Transfers the source operand data to the destination. The transferred data is a word, the top word of the register is stored as the word data.
Note
When one of the guard bit registers A0G and A1G is the source operand it is sign extended and stored as a word.
DSP
movs.l @-As,Ds
As-4 -> As, (As) -> Ds
111101AADDDD0010
1
1
Description
Transfers the source operand data to the destination. The transferred data is a longword. When the destination operand is a register with guard bits, the sign is extended and stored in the guard bits.
DSP
movs.l @As,Ds
(As) -> Ds
111101AADDDD0110
1
1
Description
Transfers the source operand data to the destination. The transferred data is a longword. When the destination operand is a register with guard bits, the sign is extended and stored in the guard bits.
DSP
movs.l @As+,Ds
(As) -> Ds, As+4 -> As
111101AADDDD1010
1
1
Description
Transfers the source operand data to the destination. The transferred data is a longword. When the destination operand is a register with guard bits, the sign is extended and stored in the guard bits.
DSP
movs.l @As+Is,Ds
(As) -> Ds, As+Is -> As
111101AADDDD1110
1
1
Description
Transfers the source operand data to the destination. The transferred data is a longword. When the destination operand is a register with guard bits, the sign is extended and stored in the guard bits.
DSP
movs.l Ds,@-As
As-4 -> As, Ds -> (As)
111101AADDDD0011
1
1
Description
Transfers the source operand data to the destination. The transferred data is a longword.
Note
When one of the guard bit registers A0G and A1G is the source operand it is sign extended and stored as a word.
DSP
movs.l Ds,@As
Ds -> (As)
111101AADDDD0111
1
1
Description
Transfers the source operand data to the destination. The transferred data is a longword.
Note
When one of the guard bit registers A0G and A1G is the source operand it is sign extended and stored as a word.
DSP
movs.l Ds,@As+
Ds -> (As), As+4 -> As
111101AADDDD1011
1
1
Description
Transfers the source operand data to the destination. The transferred data is a longword.
Note
When one of the guard bit registers A0G and A1G is the source operand it is sign extended and stored as a word.
DSP
movs.l Ds,@As+Is
Ds -> (As), As+Is -> As
111101AADDDD1111
1
1
Description
Transfers the source operand data to the destination. The transferred data is a longword.
Note
When one of the guard bit registers A0G and A1G is the source operand it is sign extended and stored as a word.
DSP ALU Arithmetic Operation Instructions
DSP
pabs Sx,Dz
If Sx >= 0: Sx -> Dz If Sx < 0: 0 - Sx -> Dz
111110********** 10001000xx00zzzz
Update
1
1
Description
Finds absolute values. When the Sx operand is positive, the contents of the operand are transferred to the Dz operand. If the value is negative, the value of the Sx operand is subtracted from 0 and stored in the Dz operand.
The DC bit of the DSR register are updated according to the specifications of the CS bits. The N, Z, V, and GT bits of the DSR register are updated.
Operation
void pabs_sx (void) { DSP_ALU_SRC1 = 0; DSP_ALU_SRC1G = 0;
switch (EX2_SX) { case 0x0: DSP_ALU_SRC2 = X0; if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0; break;
case 0x1: DSP_ALU_SRC2 = X1; if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0; break;
case 0x2: DSP_ALU_SRC2 = A0; DSP_ALU_SRC2G = A0G; break;
case 0x3: DSP_ALU_SRC2 = A1; DSP_ALU_SRC2G = A1G; break; }
if (DSP_ALU_SRC2G_BIT7 == 0) { // positive value DSP_ALU_DST = 0x0 + DSP_ALU_SRC2; carry_bit = 0; DSP_ALU_DSTG_LSB8 = 0x0 + DSP_ALU_SRC2G_LSB8 + carry_bit; } else { // negative value DSP_ALU_DST = 0x0 - DSP_ALU_SRC2; borrow_bit = 1; DSP_ALU_DSTG_LSB8 = 0x0 - DSP_ALU_SRC2G_LSB8 - borrow_bit; }
overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV); #include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c"
if (DSP_ALU_SRC2G_BIT7 == 0) { #include "fixed_pt_plus_dc_bit.c" } else { overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV); #include "fixed_pt_minus_dc_bit.c" } }
DSP
pabs Sy,Dz
If Sy >= 0: Sy -> Dz If Sy < 0: 0 - Sy -> Dz
111110********** 1010100000yyzzzz
Update
1
1
Description
Finds absolute values. When the Sy operand is positive, the contents of the operand are transferred to the Dz operand. If the value is negative, the value of the Sy operand is subtracted from 0 and stored in the Dz operand.
The DC bit of the DSR register are updated according to the specifications of the CS bits. The N, Z, V, and GT bits of the DSR register are updated.
Operation
void pabs_sy (void) { DSP_ALU_SRC1 = 0; DSP_ALU_SRC1G = 0;
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
if (DSP_ALU_SRC2G_BIT7 == 0) { // positive value DSP_ALU_DST = 0x0 + DSP_ALU_SRC2; carry_bit = 0; DSP_ALU_DSTG_LSB8 = 0x0 + DSP_ALU_SRC2G_LSB8 + carry_bit; } else { // negative value DSP_ALU_DST = 0x0 - DSP_ALU_SRC2; borrow_bit = 1; DSP_ALU_DSTG_LSB8 = 0x0 - DSP_ALU_SRC2G_LSB8 - borrow_bit; }
overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV); #include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c"
if (DSP_ALU_SRC2G_BIT7 == 0) { #include "fixed_pt_plus_dc_bit.c" } else { overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV); #include "fixed_pt_minus_dc_bit.c" } }
DSP
padd Sx,Sy,Dz
Sx + Sy -> Dz
111110********** 10110001xxyyzzzz
Update
1
1
Description
Adds the contents of the Sx and Sy operands and stores the result in the Dz operand. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Note
The DC bit is updated depending on the state of the CS [2:0] bit immediately before the operation.
Operation
void padd (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 + DSP_ALU_SRC2;
carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB);
DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit;
overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV); #include "fixed_pt_overflow_protection.c"
#include "fixed_pt_unconditional_update.c" #include "fixed_pt_plus_dc_bit.c" }
Example
PADD X0,Y0,A0 NOPX NOPY ! Before execution: X0 = 0x22222222, Y0 = 0x33333333, A0 = 0x123456789A ! After execution: X0 = 0x22222222, Y0 = 0x33333333, A0 = 0x0055555555
DSP
dct padd Sx,Sy,Dz
If DC = 1: Sx + Sy -> Dz Else: nop
111110********** 10110010xxyyzzzz
1
1
Description
Conditionally adds the contents of the Sx and Sy operands and stores the result in the Dz operand. The instruction is executed of the DC bit is set to 1. Otherwise no operation is performed. The DC, N, Z, V, and GT bits are not updated.
Operation
void padd_dct (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 + DSP_ALU_SRC2;
carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB);
DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit;
overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV); #include "fixed_pt_overflow_protection.c"
if (DC == 1) { DSP_REG [ex2_dz_no] = DSP_ALU_DST; if(ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no==1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf padd Sx,Sy,Dz
If DC = 0: Sx + Sy -> Dz Else: nop
111110********** 10110011xxyyzzzz
1
1
Description
Conditionally adds the contents of the Sx and Sy operands and stores the result in the Dz operand. The instruction is executed of the DC bit is set to 0. Otherwise no operation is performed. The DC, N, Z, V, and GT bits are not updated.
Operation
void padd_dct (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 + DSP_ALU_SRC2;
carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB);
DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit;
overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV); #include "fixed_pt_overflow_protection.c"
if (DC == 0) { DSP_REG [ex2_dz_no] = DSP_ALU_DST; if(ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no==1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
padd Sx,Sy,Du pmuls Se,Sf,Dg
Sx + Sy -> Du MSW of Se * MSW of Sf -> Dg
111110********** 0111eeffxxyygguu
Update
1
1
Description
Adds the contents of the Sx and Sy operands and stores the result in the Du operand. The contents of the top word of the Se and Sf operands are multiplied as signed and the result stored in the Dg operand. These two processes are executed simultaneously in parallel.
The DC bit of the DSR register is updated according to the results of the ALU operation and the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated according to the results of the ALU operation.
Note
Since the PMULS is fixed decimal point multiplication, the operation result is different from that of MULS even though the source data is the same.
Operation
void padd_pmuls (void) { DSP_ALU_DST = DSP_ALU_SRC1 + DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
switch (EX2_DU) { case 0x0: X0 = DSP_ALU_DST; negative_bit = DSP_ALU_DSTG_BIT7; zero_bit = (DSP_ALU_DST == 0) & (DSP_ALU_DSTG_LSB8 == 0); break;
case 0x1: Y0 = DSP_ALU_DST; negative_bit = DSP_ALU_DSTG_BIT7; zero_bit = (DSP_ALU_DST == 0) & (DSP_ALU_DSTG_LSB8 == 0); break;
case 0x2: A0 = DSP_ALU_DST; A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; negative_bit = DSP_ALU_DSTG_BIT7; zero_bit = (DSP_ALU_DST == 0) & (DSP_ALU_DSTG_LSB8 == 0); break;
case 0x3: A1 = DSP_ALU_DST; A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; negative_bit = DSP_ALU_DSTG_BIT7; zero_bit = (DSP_ALU_DST == 0) & (DSP_ALU_DSTG_LSB8 == 0); break; }
#include "fixed_pt_plus_dc_bit.c" }
Example
PADD A0,M0,A0 PMULS X0,YO,MO NOPX NOPY ! Before execution: X0 = 0x00020000, Y0 = 0x00030000, M0 = 0x22222222, A0 = 0x0055555555 ! After execution: X0 = 0x00020000, Y0 = 0x00030000, M0 = 0x0000000C, A0 = 0x0077777777
DSP
paddc Sx,Sy,Dz
Sx + Sy + DC -> Dz
111110********** 10110000xxyyzzzz
Update
1
1
Description
Adds the contents of the Sx and Sy operands to the DC bit and stores the result in the Dz operand. The DC bit of the DSR register is updated as the carry flag. The N, Z, V, and GT bits of the DSR register are also updated.
Note
The DC bit is updated as the carry flag after execution of the PADDC instruction regardless of the CS bits.
CS[2:0] = ***: Always operate as Carry or Borrow mode, regardless of the status of the DC bit.
Operation
void paddc (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 + DSP_ALU_SRC2 + DSPDCBIT;
carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB);
DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit;
overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c" #include "fixed_pt_dc_always_carry.c" }
Example
PADDC X0,Y0,M0 NOPX NOPY ! Before execution: X0 = 0xB3333333, Y0 = 0x55555555 M0 = 0x12345678, DC = 0 ! After execution: X0 = 0xB3333333, Y0 = 0x55555555 M0 = 0x08888888, DC = 1
PADDC X0,Y0,M0 NOPX NOPY ! Before execution: X0 = 0x33333333, Y0 = 0x55555555 M0 = 0x12345678, DC = 1 ! After execution: X0 = 0x33333333, Y0 = 0x55555555 M0 = 0x88888889, DC = 0
DSP
pclr Dz
0x00000000 -> Dz
111110********** 100011010000zzzz
Update
1
1
Description
Clears the Dz operand. The DC bit of the DSR register is updated according to the specifications for the CS bits. The Z bit of the DSR register is set to 1. The N, V, and GT bits are cleared to 0.
Operation
void pclr (void) { DSP_REG[ex2_dz_no] = 0x0;
if (ex2_dz_no == 0) A0G = 0x0; else if (ex2_dz_no == 1) A1G = 0x0;
carry_bit = 0; negative_bit = 0; zero_bit = 1; overflow_bit = 0;
#include "fixed_pt_plus_dc_bit.c" }
Example
PCLR A0 NOPX NOPY ! Before execution: A0 = 0xFF87654321 ! After execution: A0 = 0x0000000000
DSP
dct pclr Dz
If DC = 1: 0x00000000 -> Dz Else: nop
111110********** 100011100000zzzz
1
1
Description
Conditionally clears the Dz operand. The instruction is executed when the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void pclr_dct (void) { if (DC == 1) DSP_REG[ex2_dz_no] = 0x0; }
DSP
dcf pclr Dz
If DC = 0: 0x00000000 -> Dz Else: nop
111110********** 100011110000zzzz
1
1
Description
Conditionally clears the Dz operand. The instruction is executed when the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void pclr_dcf (void) { if (DC == 0) DSP_REG[ex2_dz_no] = 0x0; }
DSP
pcmp Sx,Sy
Sx - Sy
111110********** 10000100xxyy0000
Update
1
1
Description
Subtracts the contents of the Sy operand from the Sx operand. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void pcmp (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 - DSP_ALU_SRC2;
carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB);
borrow_bit = ! carry_bit;
DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit;
negative_bit = DSP_ALU_DSTG_BIT7; zero_bit = (DSP_ALU_DST == 0) & (DSP_ALU_DSTG_LSB8 == 0); overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c" #include "fixed_pt_minus_dc_bit.c"
}
Example
PCMP X0,Y0 NOPX NOPY ! Before execution: X0 = 0x22222222, Y0 = 0x33333333 ! After execution: X0 = 0x22222222, Y0 = 0x33333333 ! N = 1, Z = 0, V = 0, GT = 0
DSP
pcopy Sx,Dz
Sx -> Dz
111110********** 11011001xx00zzzz
Update
1
1
Description
Stores the Sx operand in the Dz operand. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits are also updated.
Operation
void pcopy_sx (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
DSP_ALU_SRC2 = 0; DSP_ALU_SRC2G = 0;
DSP_ALU_DST = DSP_ALU_SRC1 + DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c" #include "fixed_pt_plus_dc_bit.c" }
DSP
pcopy Sy,Dz
Sy -> Dz
111110********** 1111100100yyzzzz
Update
1
1
Description
Stores the Sy operand in the Dz operand. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits are also updated.
Operation
void pcopy_sy (void) { DSP_ALU_SRC1 = 0; DSP_ALU_SRC1G = 0;
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 + DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c" #include "fixed_pt_plus_dc_bit.c" }
Example
PCOPY X0,A0 NOPX NOPY ! Before execution: X0 = 0x55555555, A0 = 0xFFFFFFFF ! After execution: X0 = 0x55555555, A0 = 0x0055555555
DSP
dct pcopy Sx,Dz
If DC = 1: Sx -> Dz Else: nop
111110********** 11011010xx00zzzz
1
1
Description
Conditionally stores the Sx operand in the Dz operand. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void pcopy_sx_dct (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
DSP_ALU_SRC2 = 0; DSP_ALU_SRC2G = 0;
DSP_ALU_DST = DSP_ALU_SRC1 + DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
if (DC == 1) { DSP_REG[ex2_dz_no] = DSP_ALU_DST; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dct pcopy Sy,Dz
If DC = 1: Sy -> Dz Else: nop
111110********** 1111101000yyzzzz
1
1
Description
Conditionally stores the Sy operand in the Dz operand. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void pcopy_sy_dct (void) { DSP_ALU_SRC1 = 0; DSP_ALU_SRC1G = 0;
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 + DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
if (DC == 1) { DSP_REG[ex2_dz_no] = DSP_ALU_DST; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf pcopy Sx,Dz
If DC = 0: Sx -> Dz Else: nop
111110********** 11011011xx00zzzz
1
1
Description
Conditionally stores the Sx operand in the Dz operand. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void pcopy_sx_dcf (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
DSP_ALU_SRC2 = 0; DSP_ALU_SRC2G = 0;
DSP_ALU_DST = DSP_ALU_SRC1 + DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
if (DC == 0) { DSP_REG[ex2_dz_no] = DSP_ALU_DST; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf pcopy Sy,Dz
If DC = 0: Sy -> Dz Else: nop
111110********** 1111101100yyzzzz
1
1
Description
Conditionally stores the Sy operand in the Dz operand. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void pcopy_sy_dcf (void) { DSP_ALU_SRC1 = 0; DSP_ALU_SRC1G = 0;
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 + DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
if (DC == 0) { DSP_REG[ex2_dz_no] = DSP_ALU_DST; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
pneg Sx,Dz
0 - Sx -> Dz
111110********** 11001001xx00zzzz
Update
1
1
Description
Reverses the sign. Subtracts the Sx operand from 0 and stores the result in the Dz operand. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void pneg_sx (void) { DSP_ALU_SRC1 = 0; DSP_ALU_SRC1G = 0;
switch (EX2_SX) { case 0x0: DSP_ALU_SRC2 = X0; if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0; break;
case 0x1: DSP_ALU_SRC2 = X1; if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0; break;
case 0x2: DSP_ALU_SRC2 = A0; DSP_ALU_SRC2G = A0G; break;
case 0x3: DSP_ALU_SRC2 = A1; DSP_ALU_SRC2G = A1G; break; }
DSP_ALU_DST = DSP_ALU_SRC1 - DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c" #include "fixed_pt_minus_dc_bit.c" }
DSP
pneg Sy,Dz
0 - Sy -> Dz
111110********** 1110100100yyzzzz
Update
1
1
Description
Reverses the sign. Subtracts the Sy operand from 0 and stores the result in the Dz operand. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void pneg_sy (void) { DSP_ALU_SRC1 = 0; DSP_ALU_SRC1G = 0;
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 - DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c" #include "fixed_pt_minus_dc_bit.c" }
DSP
dct pneg Sx,Dz
If DC = 1: 0 - Sx -> Dz Else: nop
111110********** 11001010xx00zzzz
1
1
Description
Conditionally reverses the sign. The instruction is executed if the DC bit is set to 1. Subtracts the Sx operand from 0 and stores the result in the Dz operand. The DC, N, Z, V, and GT bits are not updated.
Operation
void pneg_sx_dct (void) { DSP_ALU_SRC1 = 0; DSP_ALU_SRC1G = 0;
switch (EX2_SX) { case 0x0: DSP_ALU_SRC2 = X0; if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0; break;
case 0x1: DSP_ALU_SRC2 = X1; if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0; break;
case 0x2: DSP_ALU_SRC2 = A0; DSP_ALU_SRC2G = A0G; break;
case 0x3: DSP_ALU_SRC2 = A1; DSP_ALU_SRC2G = A1G; break; }
DSP_ALU_DST = DSP_ALU_SRC1 - DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
if (DC == 1) { DSP_REG[ex2_dz_no] = DSP_ALU_DST; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dct pneg Sy,Dz
If DC = 1: 0 - Sy -> Dz Else: nop
111110********** 1110101000yyzzzz
1
1
Description
Conditionally reverses the sign. The instruction is executed if the DC bit is set to 1. Subtracts the Sy operand from 0 and stores the result in the Dz operand. The DC, N, Z, V, and GT bits are not updated.
Operation
void pneg_sy_dct (void) { DSP_ALU_SRC1 = 0; DSP_ALU_SRC1G = 0;
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 - DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
if (DC == 1) { DSP_REG[ex2_dz_no] = DSP_ALU_DST; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf pneg Sx,Dz
If DC = 0: 0 - Sx -> Dz Else: nop
111110********** 11001011xx00zzzz
1
1
Description
Conditionally reverses the sign. The instruction is executed if the DC bit is set to 0. Subtracts the Sx operand from 0 and stores the result in the Dz operand. The DC, N, Z, V, and GT bits are not updated.
Operation
void pneg_sx_dcf (void) { DSP_ALU_SRC1 = 0; DSP_ALU_SRC1G = 0;
switch (EX2_SX) { case 0x0: DSP_ALU_SRC2 = X0; if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0; break;
case 0x1: DSP_ALU_SRC2 = X1; if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0; break;
case 0x2: DSP_ALU_SRC2 = A0; DSP_ALU_SRC2G = A0G; break;
case 0x3: DSP_ALU_SRC2 = A1; DSP_ALU_SRC2G = A1G; break; }
DSP_ALU_DST = DSP_ALU_SRC1 - DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
if (DC == 0) { DSP_REG[ex2_dz_no] = DSP_ALU_DST; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf pneg Sy,Dz
If DC = 0: 0 - Sy -> Dz Else: nop
111110********** 1110101100yyzzzz
1
1
Description
Conditionally reverses the sign. The instruction is executed if the DC bit is set to 0. Subtracts the Sy operand from 0 and stores the result in the Dz operand. The DC, N, Z, V, and GT bits are not updated.
Operation
void pneg_sy_dcf (void) { DSP_ALU_SRC1 = 0; DSP_ALU_SRC1G = 0;
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 - DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
if (DC == 0) { DSP_REG[ex2_dz_no] = DSP_ALU_DST; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
psub Sx,Sy,Dz
Sx - Sy -> Dz
111110********** 10100001xxyyzzzz
Update
1
1
Description
Subtracts the contents of the Sy operand from the Sx operand and stores the result in the Dz operand. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are updated.
Operation
void psub (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 - DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c" #include "fixed_pt_minus_dc_bit.c" }
Example
PSUB X0,Y0,A0 NOPX NOPY ! Before execution: X0 = 0x55555555, Y0 = 0x33333333, A0 = 0x123456789A ! After execution: X0 = 0x55555555, Y0 = 0x33333333, A0 = 0x0022222222
DSP
dct psub Sx,Sy,Dz
If DC = 1: Sx - Sy -> Dz Else: nop
111110********** 10100010xxyyzzzz
1
1
Description
Conditionally subtracts the contents of the Sy operand from the Sx operand and stores the result in the Dz operand. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void psub_dct (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 - DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
if (DC == 1) { DSP_REG[ex2_dz_no] = DSP_ALU_DST; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf psub Sx,Sy,Dz
If DC = 0: Sx - Sy -> Dz Else: nop
111110********** 10100011xxyyzzzz
1
1
Description
Conditionally subtracts the contents of the Sy operand from the Sx operand and stores the result in the Dz operand. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void psub_dct (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 - DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
if (DC == 0) { DSP_REG[ex2_dz_no] = DSP_ALU_DST; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
psub Sx,Sy,Du pmuls Se,Sf,Dg
Sx - Sy -> Du MSW of Se * MSW of Sf -> Dg
111110********** 0110eeffxxyygguu
Update
1
1
Description
Subtracts the contents of the Sy operand from the Sx operand and stores the result in the Du operand. The contents of the top word of the Se and Sf operands are multiplied as signed and the result stored in the Dg operand. These two processes are executed simultaneously in parallel.
The DC bit of the DSR register is updated according to the results of the ALU operation and the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated according to the results of the ALU operation.
Operation
void psub_pmuls (void) { DSP_ALU_DST = DSP_ALU_SRC1 - DSP_ALU_SRC2; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
switch (EX2_DU) { case 0x0: X0 = DSP_ALU_DST; negative_bit = DSP_ALU_DST_MSB; zero_bit = (DSP_ALU_DST == 0); break;
case 0x1: Y0 = DSP_ALU_DST; negative_bit = DSP_ALU_DST_MSB; zero_bit = (DSP_ALU_DST == 0); break;
case 0x2: A0 = DSP_ALU_DST; A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; negative_bit = DSP_ALU_DSTG_BIT7; zero_bit = (DSP_ALU_DST == 0) & (DSP_ALU_DSTG_LSB8 == 0); break;
case 0x3: A1 = DSP_ALU_DST; A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; negative_bit = DSP_ALU_DSTG_BIT7; zero_bit = (DSP_ALU_DST == 0) & (DSP_ALU_DSTG_LSB8 == 0); break; }
#include "fixed_pt_minus_dc_bit.c" }
Example
PSUB A0,M0,A0 PMULS X0,Y0,M0 NOPX NOPY ! Before execution: X0 = 0x00020000, Y0 = 0xFFFE0000, M0 = 0x33333333, A0 = 0x0022222222 ! After execution: X0 = 0x00020000, Y0 = 0xFFFE0000, M0 = 0xFFFFFFF8, A0 = 0x55555555
DSP
psubc Sx,Sy,Dz
Sx - Sy - DC -> Dz
111110********** 10100000xxyyzzzz
Update
1
1
Description
Subtracts the contents of the Sy operand and the DC bit from the Sx operand and stores the result in the Dz operand. The DC bit of the DSR register is updated as the borrow flag. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void psubc (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
DSP_ALU_DST = DSP_ALU_SRC1 - DSP_ALU_SRC2 - DSPDCBIT; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = MINUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c" #include "fixed_pt_dc_always_borrow.c" }
Example
PSUBC X0,Y0,M0 NOPX NOPY ! Before execution: X0 = 0x33333333, Y0 = 0x55555555 M0 = 0x0012345678, DC = 0 ! After execution: X0 = 0x33333333, Y0 = 0x55555555 M0 = 0xFFDDDDDDDE, DC = 1
PSUBC X0,Y0,M0 NOPX NOPY ! Before execution: X0 = 0x33333333, Y0 = 0x55555555 M0 = 0x0012345678, DC = 1 ! After execution: X0 = 0x33333333, Y0 = 0x55555555 M0 = 0xFFDDDDDDDD, DC = 1
DSP
pdec Sx,Dz
MSW of Sx - 1 -> MSW of Dz, clear LSW of Dz
111110********** 10001001xx00zzzz
Update
1
1
Description
Subtracts 1 from the top word of the Sx operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Note
The bottom word of the destination register is ignored when the DC bit is updated.
Operation
void pdec_sx (void) { DSP_ALU_SRC2 = 0x1; DSP_ALU_SRC2G = 0x0;
switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW - 1; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "integer_overflow_protection.c" #include "integer_unconditional_update.c" #include "integer_minus_dc_bit.c" }
DSP
pdec Sy,Dz
MSW of Sy - 1 -> MSW of Dz, clear LSW of Dz
111110********** 1010100100yyzzzz
Update
1
1
Description
Subtracts 1 from the top word of the Sy operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Note
The bottom word of the destination register is ignored when the DC bit is updated.
Operation
void pdec_sy (void) { DSP_ALU_SRC2 = 0x1; DSP_ALU_SRC2G = 0x0;
switch (EX2_SY) { case 0x0: DSP_ALU_SRC1 = Y0; break;
case 0x1: DSP_ALU_SRC1 = Y1; break;
case 0x2: DSP_ALU_SRC1 = M0; break;
case 0x3: DSP_ALU_SRC1 = M1; break; }
if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0;
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW - 1; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "integer_overflow_protection.c" #include "integer_unconditional_update.c" #include "integer_minus_dc_bit.c" }
DSP
dct pdec Sx,Dz
If DC = 1: MSW of Sx - 1 -> MSW of DZ, clear LSW of Dz Else: nop
111110********** 10001010xx00zzzz
1
1
Description
Conditionally subtracts 1 from the top word of the Sx operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void pdec_sx_dct (void) { DSP_ALU_SRC2 = 0x1; DSP_ALU_SRC2G = 0x0;
switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW - 1; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "integer_overflow_protection.c"
if (DC == 1) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dct pdec Sy,Dz
If DC = 1: MSW of Sy - 1 -> MSW of DZ, clear LSW of Dz Else: nop
111110********** 1010101000yyzzzz
1
1
Description
Conditionally subtracts 1 from the top word of the Sy operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void pdec_sy_dct (void) { DSP_ALU_SRC2 = 0x1; DSP_ALU_SRC2G = 0x0;
switch (EX2_SY) { case 0x0: DSP_ALU_SRC1 = Y0; break;
case 0x1: DSP_ALU_SRC1 = Y1; break;
case 0x2: DSP_ALU_SRC1 = M0; break;
case 0x3: DSP_ALU_SRC1 = M1; break; }
if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0;
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW - 1; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "integer_overflow_protection.c"
if (DC == 1) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf pdec Sx,Dz
If DC = 0: MSW of Sx - 1 -> MSW of DZ, clear LSW of Dz Else: nop
111110********** 10001011xx00zzzz
1
1
Description
Conditionally subtracts 1 from the top word of the Sx operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void pdec_sx_dcf (void) { DSP_ALU_SRC2 = 0x1; DSP_ALU_SRC2G = 0x0;
switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW - 1; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "integer_overflow_protection.c"
if (DC == 0) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf pdec Sy,Dz
If DC = 0: MSW of Sy - 1 -> MSW of DZ, clear LSW of Dz Else: nop
111110********** 1010101100yyzzzz
1
1
Description
Conditionally subtracts 1 from the top word of the Sy operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void pdec_sy_dcf (void) { DSP_ALU_SRC2 = 0x1; DSP_ALU_SRC2G = 0x0;
switch (EX2_SY) { case 0x0: DSP_ALU_SRC1 = Y0; break;
case 0x1: DSP_ALU_SRC1 = Y1; break;
case 0x2: DSP_ALU_SRC1 = M0; break;
case 0x3: DSP_ALU_SRC1 = M1; break; }
if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0;
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW - 1; carry_bit = ((DSP_ALU_SRC1_MSB | ! DSP_ALU_SRC2_MSB) && ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & ! DSP_ALU_SRC2_MSB); borrow_bit = ! carry_bit; DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 - DSP_ALU_SRC2G_LSB8 - borrow_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "integer_overflow_protection.c"
if (DC == 0) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
pinc Sx,Dz
MSW of Sy + 1 -> MSW of Dz, clear LSW of Dz
111110********** 10011001xx00zzzz
Update
1
1
Description
Adds 1 to the top word of the Sx operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void pinc_sx (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW + 1; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "integer_overflow_protection.c" #include "integer_unconditional_update.c" #include "integer_plus_dc_bit.c" }
DSP
pinc Sy,Dz
MSW of Sy + 1 -> MSW of Dz, clear LSW of Dz
111110********** 1011100100yyzzzz
Update
1
1
Description
Adds 1 to the top word of the Sy operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void pinc_sy (void) { switch (EX2_SY) { case 0x0: DSP_ALU_SRC1 = Y0; break;
case 0x1: DSP_ALU_SRC1 = Y1; break;
case 0x2: DSP_ALU_SRC1 = M0; break;
case 0x3: DSP_ALU_SRC1 = M1; break; }
if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0;
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW + 1; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "integer_overflow_protection.c" #include "integer_unconditional_update.c" #include "integer_plus_dc_bit.c" }
DSP
dct pinc Sx,Dz
If DC = 1: MSW of Sx + 1 -> MSW of Dz, clear LSW of Dz Else: nop
111110********** 10011010xx00zzzz
1
1
Description
Conditionally adds 1 to the top word of the Sx operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void pinc_sx_dct (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW + 1; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "integer_overflow_protection.c"
if (DC == 1) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dct pinc Sy,Dz
If DC = 1: MSW of Sy + 1 -> MSW of Dz, clear LSW of Dz Else: nop
111110********** 1011101000yyzzzz
1
1
Description
Conditionally adds 1 to the top word of the Sy operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void pinc_sy_dct (void) { switch (EX2_SY) { case 0x0: DSP_ALU_SRC1 = Y0; break;
case 0x1: DSP_ALU_SRC1 = Y1; break;
case 0x2: DSP_ALU_SRC1 = M0; break;
case 0x3: DSP_ALU_SRC1 = M1; break; }
if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0;
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW + 1; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "integer_overflow_protection.c"
if (DC == 1) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf pinc Sx,Dz
If DC = 0: MSW of Sx + 1 -> MSW of Dz, clear LSW of Dz Else: nop
111110********** 10011011xx00zzzz
1
1
Description
Conditionally adds 1 to the top word of the Sx operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void pinc_sx_dcf (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW + 1; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "integer_overflow_protection.c"
if (DC == 0) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf pinc Sy,Dz
If DC = 0: MSW of Sy + 1 -> MSW of Dz, clear LSW of Dz Else: nop
111110********** 1011101100yyzzzz
1
1
Description
Conditionally adds 1 to the top word of the Sy operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void pinc_sy_dcf (void) { switch (EX2_SY) { case 0x0: DSP_ALU_SRC1 = Y0; break;
case 0x1: DSP_ALU_SRC1 = Y1; break;
case 0x2: DSP_ALU_SRC1 = M0; break;
case 0x3: DSP_ALU_SRC1 = M1; break; }
if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0;
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW + 1; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "integer_overflow_protection.c"
if (DC == 0) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
pdmsb Sx,Dz
Sx data MSB position -> MSW of Dz, clear LSW of Dz
111110********** 10011101xx00zzzz
Update
1
1
Description
Finds the first position to change in the lineup of Sx operand bits and stores the bit position in the Dz operand. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void pdmsb_sx (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
short int i; unsigned char msb, src1g; unsigned long src1 = DSP_ALU_SRC1; msb = DSP_ALU_SRC1G_BIT7; src1g = (DSP_ALU_SRC1G_LSB8 << 1); for (i = 38; ((msb == (src1g >> 7)) && (i >= 32)); i--) src1g <<= 1;
if (i == 31) for(i; ((msb == (src1 >> 31)) && (i >= 0)); i--) src1 <<= 1;
DSP_ALU_DST = 0x0; DSP_ALU_DST_HW = (short int)(30 - i); if (DSP_ALU_DST_MSB) DSP_ALU_DSTG_LSB8 = 0xFF; else DSP_ALU_DSTG_LSB8 = 0x0;
carry_bit = 0; overflow_bit = 0;
#include "integer_unconditional_update.c" #include "integer_plus_dc_bit.c" }
DSP
pdmsb Sy,Dz
Sy data MSB position -> MSW of Dz, clear LSW of Dz
111110********** 1011110100yyzzzz
Update
1
1
Description
Finds the first position to change in the lineup of Sy operand bits and stores the bit position in the Dz operand. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void pdmsb_sy (void) { switch (EX2_SY) { case 0x0: DSP_ALU_SRC1 = Y0; break;
case 0x1: DSP_ALU_SRC1 = Y1; break;
case 0x2: DSP_ALU_SRC1 = M0; break;
case 0x3: DSP_ALU_SRC1 = M1; break; }
if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0;
short int i; unsigned char msb, src1g; unsigned long src1 = DSP_ALU_SRC1; msb = DSP_ALU_SRC1G_BIT7; src1g = (DSP_ALU_SRC1G_LSB8 << 1); for (i = 38; ((msb == (src1g >> 7)) && (i >= 32)); i--) src1g <<= 1;
if (i == 31) for(i; ((msb == (src1 >> 31)) && (i >= 0)); i--) src1 <<= 1;
DSP_ALU_DST = 0x0; DSP_ALU_DST_HW = (short int)(30 - i); if (DSP_ALU_DST_MSB) DSP_ALU_DSTG_LSB8 = 0xFF; else DSP_ALU_DSTG_LSB8 = 0x0;
carry_bit = 0; overflow_bit = 0;
#include "integer_unconditional_update.c" #include "integer_plus_dc_bit.c" }
DSP
dct pdmsb Sx,Dz
If DC = 1: Sx data MSB position -> MSW of Dz, clear LSW of Dz Else: nop
111110********** 10011110xx00zzzz
1
1
Description
Conditionally finds the first position to change in the lineup of Sx operand bits and stores the bit position in the Dz operand. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void pdmsb_sx_dct (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
short int i; unsigned char msb, src1g; unsigned long src1 = DSP_ALU_SRC1; msb = DSP_ALU_SRC1G_BIT7; src1g = (DSP_ALU_SRC1G_LSB8 << 1); for (i = 38; ((msb == (src1g >> 7)) && (i >= 32)); i--) src1g <<= 1;
if (i == 31) for(i; ((msb == (src1 >> 31)) && (i >= 0)); i--) src1 <<= 1;
DSP_ALU_DST = 0x0; DSP_ALU_DST_HW = (short int)(30 - i); if (DSP_ALU_DST_MSB) DSP_ALU_DSTG_LSB8 = 0xFF; else DSP_ALU_DSTG_LSB8 = 0x0;
carry_bit = 0;
if (DC == 1) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dct pdmsb Sy,Dz
If DC = 1: Sy data MSB position -> MSW of Dz, clear LSW of Dz Else: nop
111110********** 1011111000yyzzzz
1
1
Description
Conditionally finds the first position to change in the lineup of Sy operand bits and stores the bit position in the Dz operand. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void pdmsb_sy_dct (void) { switch (EX2_SY) { case 0x0: DSP_ALU_SRC1 = Y0; break;
case 0x1: DSP_ALU_SRC1 = Y1; break;
case 0x2: DSP_ALU_SRC1 = M0; break;
case 0x3: DSP_ALU_SRC1 = M1; break; }
if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0;
short int i; unsigned char msb, src1g; unsigned long src1 = DSP_ALU_SRC1; msb = DSP_ALU_SRC1G_BIT7; src1g = (DSP_ALU_SRC1G_LSB8 << 1); for (i = 38; ((msb == (src1g >> 7)) && (i >= 32)); i--) src1g <<= 1;
if (i == 31) for(i; ((msb == (src1 >> 31)) && (i >= 0)); i--) src1 <<= 1;
DSP_ALU_DST = 0x0; DSP_ALU_DST_HW = (short int)(30 - i); if (DSP_ALU_DST_MSB) DSP_ALU_DSTG_LSB8 = 0xFF; else DSP_ALU_DSTG_LSB8 = 0x0;
carry_bit = 0;
if (DC == 1) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf pdmsb Sx,Dz
If DC = 0: Sx data MSB position -> MSW of Dz, clear LSW of Dz Else: nop
111110********** 10011111xx00zzzz
1
1
Description
Conditionally finds the first position to change in the lineup of Sx operand bits and stores the bit position in the Dz operand. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void pdmsb_sx_dcf (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
short int i; unsigned char msb, src1g; unsigned long src1 = DSP_ALU_SRC1; msb = DSP_ALU_SRC1G_BIT7; src1g = (DSP_ALU_SRC1G_LSB8 << 1); for (i = 38; ((msb == (src1g >> 7)) && (i >= 32)); i--) src1g <<= 1;
if (i == 31) for(i; ((msb == (src1 >> 31)) && (i >= 0)); i--) src1 <<= 1;
DSP_ALU_DST = 0x0; DSP_ALU_DST_HW = (short int)(30 - i); if (DSP_ALU_DST_MSB) DSP_ALU_DSTG_LSB8 = 0xFF; else DSP_ALU_DSTG_LSB8 = 0x0;
carry_bit = 0;
if (DC == 0) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf pdmsb Sy,Dz
If DC = 0: Sy data MSB position -> MSW of Dz, clear LSW of Dz Else: nop
111110********** 1011111100yyzzzz
1
1
Description
Conditionally finds the first position to change in the lineup of Sy operand bits and stores the bit position in the Dz operand. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void pdmsb_sy_dcf (void) { switch (EX2_SY) { case 0x0: DSP_ALU_SRC1 = Y0; break;
case 0x1: DSP_ALU_SRC1 = Y1; break;
case 0x2: DSP_ALU_SRC1 = M0; break;
case 0x3: DSP_ALU_SRC1 = M1; break; }
if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0;
short int i; unsigned char msb, src1g; unsigned long src1 = DSP_ALU_SRC1; msb = DSP_ALU_SRC1G_BIT7; src1g = (DSP_ALU_SRC1G_LSB8 << 1); for (i = 38; ((msb == (src1g >> 7)) && (i >= 32)); i--) src1g <<= 1;
if (i == 31) for(i; ((msb == (src1 >> 31)) && (i >= 0)); i--) src1 <<= 1;
DSP_ALU_DST = 0x0; DSP_ALU_DST_HW = (short int)(30 - i); if (DSP_ALU_DST_MSB) DSP_ALU_DSTG_LSB8 = 0xFF; else DSP_ALU_DSTG_LSB8 = 0x0;
carry_bit = 0;
if (DC == 0) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
prnd Sx,Dz
Sx + 0x00008000 -> Dz, clear LSW of Dz
111110********** 10011000xx00zzzz
1
1
Description
Does rounding. Adds the immediate data 0x00008000 to the contents of the Sx operand, stores the result in the upper word of the Dz operand, and clears the bottom word of Dz with zeros.
The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void prnd_sx (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
DSP_ALU_DST = (DSP_ALU_SRC1 + DSP_ALU_SRC2) & MASKFFFF0000; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c" #include "fixed_pt_plus_dc_bit.c" }
DSP
prnd Sy,Dz
Sy + 0x00008000 -> Dz, clear LSW of Dz
111110********** 1011100000yyzzzz
1
1
Description
Does rounding. Adds the immediate data 0x00008000 to the contents of the Sy operand, stores the result in the upper word of the Dz operand, and clears the bottom word of Dz with zeros.
The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void prnd_sy (void) { switch (EX2_SY) { case 0x0: DSP_ALU_SRC1 = Y0; break;
case 0x1: DSP_ALU_SRC1 = Y1; break;
case 0x2: DSP_ALU_SRC1 = M0; break;
case 0x3: DSP_ALU_SRC1 = M1; break; }
if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0;
DSP_ALU_DST = (DSP_ALU_SRC1 + DSP_ALU_SRC2) & MASKFFFF0000; carry_bit = ((DSP_ALU_SRC1_MSB | DSP_ALU_SRC2_MSB) & ! DSP_ALU_DST_MSB) | (DSP_ALU_SRC1_MSB & DSP_ALU_SRC2_MSB); DSP_ALU_DSTG_LSB8 = DSP_ALU_SRC1G_LSB8 + DSP_ALU_SRC2G_LSB8 + carry_bit; overflow_bit = PLUS_OP_G_OV || ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c" #include "fixed_pt_plus_dc_bit.c" }
DSP ALU Logical Operation Instructions
DSP
pand Sx,Sy,Dz
Sx & Sy -> Dz, clear LSW of Dz
111110********** 10010101xxyyzzzz
Update
1
1
Description
Does an AND of the upper word of the Sx operand and the upper word of the Sy operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Note
The bottom word of the destination register and the guard bits are ignored when the DC bit is updated.
Operation
void pand (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; break;
case 0x1: DSP_ALU_SRC1 = X1; break;
case 0x2: DSP_ALU_SRC1 = A0; break;
case 0x3: DSP_ALU_SRC1 = A1; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW & DSP_ALU_SRC2_HW;
DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // clear Guard bits else if (ex2_dz_no == 1) A1G = 0x0;
carry_bit = 0x0; negative_bit = DSP_ALU_DST_MSB; zero_bit = (DSP_ALU_DST_HW == 0); overflow_bit = 0x0;
#include "logical_dc_bit.c" }
DSP
dct pand Sx,Sy,Dz
If DC = 1: Sx & Sy -> Dz, clear LSW of Dz Else: nop
111110********** 10010110xxyyzzzz
1
1
Description
Conditionally does an AND of the upper word of the Sx operand and the upper word of the Sy operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void pand_dct (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; break;
case 0x1: DSP_ALU_SRC1 = X1; break;
case 0x2: DSP_ALU_SRC1 = A0; break;
case 0x3: DSP_ALU_SRC1 = A1; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW & DSP_ALU_SRC2_HW;
if (DC == 1) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // clear Guard bits else if (ex2_dz_no==1) A1G = 0x0; } }
DSP
dcf pand Sx,Sy,Dz
If DC = 0: Sx & Sy -> Dz, clear LSW of Dz Else: nop
111110********** 10010111xxyyzzzz
1
1
Description
Conditionally does an AND of the upper word of the Sx operand and the upper word of the Sy operand, stores the result in the upper word of the Dz operand, and clears the bottom word of the Dz operand with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void pand_dcf (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; break;
case 0x1: DSP_ALU_SRC1 = X1; break;
case 0x2: DSP_ALU_SRC1 = A0; break;
case 0x3: DSP_ALU_SRC1 = A1; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW & DSP_ALU_SRC2_HW;
if (DC == 0) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // clear Guard bits else if (ex2_dz_no==1) A1G = 0x0; } }
DSP
por Sx,Sy,Dz
Sx | Sy -> Dz, clear LSW of Dz
111110********** 10110101xxyyzzzz
Update
1
1
Description
Takes the OR of the top word of the Sx operand and the top word of the Sy operand, stores the result in the top word of the Dz operand, and clears the bottom word of Dz with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Note
The bottom word of the destination register and the guard bits are ignored when the DC bit is updated.
Operation
void por (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; break;
case 0x1: DSP_ALU_SRC1 = X1; break;
case 0x2: DSP_ALU_SRC1 = A0; break;
case 0x3: DSP_ALU_SRC1 = A1; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW | DSP_ALU_SRC2_HW;
DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // clear Guard bits else if (ex2_dz_no == 1) A1G = 0x0;
carry_bit = 0x0; negative_bit = DSP_ALU_DST_MSB; zero_bit = (DSP_ALU_DST_HW == 0); overflow_bit = 0x0;
#include "logical_dc_bit.c" }
DSP
dct por Sx,Sy,Dz
If DC = 1: Sx | Sy -> Dz, clear LSW of Dz Else: nop
111110********** 10110110xxyyzzzz
1
1
Description
Conditionally takes the OR of the top word of the Sx operand and the top word of the Sy operand, stores the result in the top word of the Dz operand, and clears the bottom word of Dz with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void por_dct (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; break;
case 0x1: DSP_ALU_SRC1 = X1; break;
case 0x2: DSP_ALU_SRC1 = A0; break;
case 0x3: DSP_ALU_SRC1 = A1; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW | DSP_ALU_SRC2_HW;
if (DC == 1) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // /* */ else if (ex2_dz_no == 1) A1G = 0x0; } }
DSP
dcf por Sx,Sy,Dz
If DC = 0: Sx | Sy -> Dz, clear LSW of Dz Else: nop
111110********** 10110111xxyyzzzz
1
1
Description
Conditionally takes the OR of the top word of the Sx operand and the top word of the Sy operand, stores the result in the top word of the Dz operand, and clears the bottom word of Dz with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void por_dcf (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; break;
case 0x1: DSP_ALU_SRC1 = X1; break;
case 0x2: DSP_ALU_SRC1 = A0; break;
case 0x3: DSP_ALU_SRC1 = A1; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW | DSP_ALU_SRC2_HW;
if (DC == 0) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // /* */ else if (ex2_dz_no == 1) A1G = 0x0; } }
DSP
pxor Sx,Sy,Dz
Sx ^ Sy -> Dz, clear LSW of Dz
111110********** 10100101xxyyzzzz
Update
1
1
Description
Takes the exclusive OR of the top word of the Sx operand and the top word of the Sy operand, stores the result in the top word of the Dz operand, and clears the bottom word of Dz with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Note
The bottom word of the destination register and the guard bits are ignored when the DC bit is updated.
Operation
void pxor (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; break;
case 0x1: DSP_ALU_SRC1 = X1; break;
case 0x2: DSP_ALU_SRC1 = A0; break;
case 0x3: DSP_ALU_SRC1 = A1; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW ^ DSP_ALU_SRC2_HW;
DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // clear Guard bits else if (ex2_dz_no == 1) A1G = 0x0;
carry_bit = 0x0; negative_bit = DSP_ALU_DST_MSB; zero_bit = (DSP_ALU_DST_HW == 0); overflow_bit = 0x0;
#include "logical_dc_bit.c" }
DSP
dct pxor Sx,Sy,Dz
If DC = 1: Sx ^ Sy -> Dz, clear LSW of Dz Else: nop
111110********** 10100110xxyyzzzz
1
1
Description
Conditionally takes the exclusive OR of the top word of the Sx operand and the top word of the Sy operand, stores the result in the top word of the Dz operand, and clears the bottom word of Dz with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void pxor_dct (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; break;
case 0x1: DSP_ALU_SRC1 = X1; break;
case 0x2: DSP_ALU_SRC1 = A0; break;
case 0x3: DSP_ALU_SRC1 = A1; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW ^ DSP_ALU_SRC2_HW;
if (DC == 1) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // clear Guard bits else if (ex2_dz_no == 1) A1G = 0x0; } }
DSP
dcf pxor Sx,Sy,Dz
If DC = 0: Sx ^ Sy -> Dz, clear LSW of Dz Else: nop
111110********** 10100111xxyyzzzz
1
1
Description
Conditionally takes the exclusive OR of the top word of the Sx operand and the top word of the Sy operand, stores the result in the top word of the Dz operand, and clears the bottom word of Dz with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void pxor_dcf (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; break;
case 0x1: DSP_ALU_SRC1 = X1; break;
case 0x2: DSP_ALU_SRC1 = A0; break;
case 0x3: DSP_ALU_SRC1 = A1; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0; break;
case 0x1: DSP_ALU_SRC2 = Y1; break;
case 0x2: DSP_ALU_SRC2 = M0; break;
case 0x3: DSP_ALU_SRC2 = M1; break; }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW ^ DSP_ALU_SRC2_HW;
if (DC == 0) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // clear Guard bits else if (ex2_dz_no == 1) A1G = 0x0; } }
DSP Fixed Decimal Point Multiplication Instructions
DSP
pmuls Se,Sf,Dg
MSW of Se * MSW of Sf -> Dg
111110********** 0100eeff0000gg00
1
1
Description
The contents of the top word of the Se and Sf operands are multiplied as signed and the result stored in the Dg operand. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Since PMULS is fixed decimal point multiplication, the operation result is different from that of MULS even though the source data is the same.
Operation
void pmuls (void) { switch (ee) // Se Operand selection bit (ee) { case 0x0: DSP_M_SRC1 = X0; break;
case 0x1: DSP_M_SRC1 = X1; break;
case 0x2: DSP_M_SRC1 = Y0; break;
case 0x3: DSP_M_SRC1 = A1; break; }
switch (ff) // Sf Operand selection bit (ff) { case 0x0: DSP_M_SRC2 = Y0; break;
case 0x1: DSP_M_SRC2 = Y1; break;
case 0x2: DSP_M_SRC2 = X0; break;
case 0x3: DSP_M_SRC2 = A1; break; }
if ((SBIT == 1) && (DSP_M_SRC1 == 0x8000) && (DSP_M_SRC2 == 0x8000)) DSP_M_DST = 0x7FFFFFFF; // overflow protection else DSP_M_DST= ((long)(short)DSP_M_SRC1 * (long)(short)DSP_M_SRC2) << 1;
if (DSP_M_DST_MSB) DSP_M_DSTG_LSB8 = 0xFF; else DSP_M_DSTG_LSB8 = 0x0;
switch (gg) // Dg Operand selection bit (gg) { case 0x0: M0 = DSP_M_DST; break;
case 0x1: M1 = DSP_M_DST; break;
case 0x2: A0 = DSP_M_DST; if (DSP_M_DSTG_LSB8 == 0x0) A0G=0x0; else A0G = 0xFFFFFFFF; break;
case 0x3: A1 = DSP_M_DST; if (DSP_M_DSTG_LSB8 == 0x0) A1G = 0x0; else A1G = 0xFFFFFFFF; break; } }
DSP Shift Operation Instructions
DSP
psha Sx,Sy,Dz
If Sy >= 0: Sx << Sy -> Dz If Sy < 0: Sx >> Sy -> Dz
111110********** 10010001xxyyzzzz
Update
1
1
Description
Arithmetically shifts the contents of the Sx or Dz operand and stores the result in the Dz operand. The amount of the shift is specified by the Sy operand. When the shift amount is positive, it shifts left. When the shift amount is negative, it shifts right. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void psha (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0 & MASK007F0000; break;
case 0x1: DSP_ALU_SRC2 = Y1 & MASK007F0000; break;
case 0x2: DSP_ALU_SRC2 = M0 & MASK007F0000; break;
case 0x3: DSP_ALU_SRC2 = M1 & MASK007F0000; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
if ((DSP_ALU_SRC2_HW & MASK0040) == 0) { // Left Shift 0 <= cnt <= 32 char cnt = DSP_ALU_SRC2_HW & MASK003F; if (cnt > 32) { printf ("\nPSHA Sz,Sy,Dz Error! Shift %2X exceed range.\n", cnt); exit (); }
DSP_ALU_DST = DSP_ALU_SRC1 << cnt;
DSP_ALU_DSTG = ((DSP_ALU_SRC1G << cnt)
| (DSP_ALU_SRC1 >> (32 - cnt))) & MASK000000FF;
carry_bit = ((DSP_ALU_DSTG & MASK00000001) == 0x1);
} else { // Right Shift 0 < cnt <= 32 char cnt = (~DSP_ALU_SRC2_HW & MASK003F) + 1; if (cnt > 32) { printf ("\nPSHA Sz,Sy,Dz Error! shift -%2X exceed range.\n", cnt); exit (); }
if ((cnt > 8) && DSP_ALU_SRC1G_BIT7)
{
// MSB copy
DSP_ALU_DST = (DSP_ALU_SRC1 >> 8) | (DSP_ALU_SRC1G << (32 - 8));
DSP_ALU_DST = (long)DSP_ALU_DST >> (cnt - 8);
}
else
DSP_ALU_DST = (DSP_ALU_SRC1 >> cnt) | (DSP_ALU_SRC1G << (32 - cnt));
DSP_ALU_DSTG_LSB8 = (char)DSP_ALU_SRC1G_LSB8 >> cnt--;
carry_bit = ((DSP_ALU_SRC1 >> cnt) & MASK00000001) == 0x1;
}
overflow_bit = ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c" #include "shift_dc_bit.c" }
DSP
dct psha Sx,Sy,Dz
If DC = 1 & Sy >= 0: Sx << Sy -> Dz If DC = 1 & Sy < 0: Sx >> Sy -> Dz If DC = 0: nop
111110********** 10010010xxyyzzzz
1
1
Description
Conditionally arithmetically shifts the contents of the Sx operand and stores the result in the Dz operand. The amount of the shift is specified by the Sy operand. When the shift amount is positive, it shifts left. When the shift amount is negative, it shifts right. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void psha_dct (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0 & MASK007F0000; break;
case 0x1: DSP_ALU_SRC2 = Y1 & MASK007F0000; break;
case 0x2: DSP_ALU_SRC2 = M0 & MASK007F0000; break;
case 0x3: DSP_ALU_SRC2 = M1 & MASK007F0000; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
if ((DSP_ALU_SRC2_HW & MASK0040) == 0) { // Left Shift 0 <= cnt <= 32 char cnt = DSP_ALU_SRC2_HW & MASK003F; if (cnt > 32) { printf ("\nPSHA Sz,Sy,Dz Error! Shift %2X exceed range.\n", cnt); exit (); }
DSP_ALU_DST = DSP_ALU_SRC1 << cnt;
DSP_ALU_DSTG = ((DSP_ALU_SRC1G << cnt)
| (DSP_ALU_SRC1 >> (32 - cnt))) & MASK000000FF;
carry_bit = ((DSP_ALU_DSTG & MASK00000001) == 0x1);
} else { // Right Shift 0 < cnt <= 32 char cnt = (~DSP_ALU_SRC2_HW & MASK003F) + 1; if (cnt > 32) { printf ("\nPSHA Sz,Sy,Dz Error! shift -%2X exceed range.\n", cnt); exit (); }
if ((cnt > 8) && DSP_ALU_SRC1G_BIT7)
{
// MSB copy
DSP_ALU_DST = (DSP_ALU_SRC1 >> 8) | (DSP_ALU_SRC1G << (32 - 8));
DSP_ALU_DST = (long)DSP_ALU_DST >> (cnt - 8);
}
else
DSP_ALU_DST = (DSP_ALU_SRC1 >> cnt) | (DSP_ALU_SRC1G << (32 - cnt));
DSP_ALU_DSTG_LSB8 = (char)DSP_ALU_SRC1G_LSB8 >> cnt--;
carry_bit = ((DSP_ALU_SRC1 >> cnt) & MASK00000001) == 0x1;
}
overflow_bit = ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
if (DC == 1) { DSP_REG[ex2_dz_no] = DSP_ALU_DST; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
dcf psha Sx,Sy,Dz
If DC = 0 & Sy >= 0: Sx << Sy -> Dz If DC = 0 & Sy < 0: Sx >> Sy -> Dz If DC = 1: nop
111110********** 10010011xxyyzzzz
1
1
Description
Conditionally arithmetically shifts the contents of the Sx operand and stores the result in the Dz operand. The amount of the shift is specified by the Sy operand. When the shift amount is positive, it shifts left. When the shift amount is negative, it shifts right. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void psha_dcf (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x1: DSP_ALU_SRC1 = X1; if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; break;
case 0x2: DSP_ALU_SRC1 = A0; DSP_ALU_SRC1G = A0G; break;
case 0x3: DSP_ALU_SRC1 = A1; DSP_ALU_SRC1G = A1G; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0 & MASK007F0000; break;
case 0x1: DSP_ALU_SRC2 = Y1 & MASK007F0000; break;
case 0x2: DSP_ALU_SRC2 = M0 & MASK007F0000; break;
case 0x3: DSP_ALU_SRC2 = M1 & MASK007F0000; break; }
if (DSP_ALU_SRC2_MSB) DSP_ALU_SRC2G = 0xFF; else DSP_ALU_SRC2G = 0x0;
if ((DSP_ALU_SRC2_HW & MASK0040) == 0) { // Left Shift 0 <= cnt <= 32 char cnt = DSP_ALU_SRC2_HW & MASK003F; if (cnt > 32) { printf ("\nPSHA Sz,Sy,Dz Error! Shift %2X exceed range.\n", cnt); exit (); }
DSP_ALU_DST = DSP_ALU_SRC1 << cnt;
DSP_ALU_DSTG = ((DSP_ALU_SRC1G << cnt)
| (DSP_ALU_SRC1 >> (32 - cnt))) & MASK000000FF;
carry_bit = ((DSP_ALU_DSTG & MASK00000001) == 0x1);
} else { // Right Shift 0 < cnt <= 32 char cnt = (~DSP_ALU_SRC2_HW & MASK003F) + 1; if (cnt > 32) { printf ("\nPSHA Sz,Sy,Dz Error! shift -%2X exceed range.\n", cnt); exit (); }
if ((cnt > 8) && DSP_ALU_SRC1G_BIT7)
{
// MSB copy
DSP_ALU_DST = (DSP_ALU_SRC1 >> 8) | (DSP_ALU_SRC1G << (32 - 8));
DSP_ALU_DST = (long)DSP_ALU_DST >> (cnt - 8);
}
else
DSP_ALU_DST = (DSP_ALU_SRC1 >> cnt) | (DSP_ALU_SRC1G << (32 - cnt));
DSP_ALU_DSTG_LSB8 = (char)DSP_ALU_SRC1G_LSB8 >> cnt--;
carry_bit = ((DSP_ALU_SRC1 >> cnt) & MASK00000001) == 0x1;
}
overflow_bit = ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c"
if (DC == 0) { DSP_REG[ex2_dz_no] = DSP_ALU_DST; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G = A0G | MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G = A1G | MASKFFFFFF00; } } }
DSP
psha #imm,Dz
If imm >= 0: Dz << imm -> Dz If imm < 0: Dz >> imm -> Dz
111110********** 00000iiiiiiizzzz
Update
1
1
Description
Arithmetically shifts the contents of the Dz operand and stores the result in the Dz operand. The amount of the shift is specified by the immediate value. When the shift amount is positive, it shifts left. When the shift amount is negative, it shifts right. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void psha_imm (void) { unsigned short tmp_imm; DSP_ALU_SRC1 = DSP_REG[ex2_dz_no];
switch (ex2_dz_no) { case 0x0: DSP_ALU_SRC1G = A0G; break;
case 0x1:
DSP_ALU_SRC1G = A1G;
break;
default:
if (DSP_ALU_SRC1_MSB)
DSP_ALU_SRC1G = 0xFF;
else
DSP_ALU_SRC1G = 0x0;
}
tmp_imm = ((EX2_LW >> 4) & MASK0000007F); // bit[10:4]
if ((tmp_imm & MASK0040) == 0) { // Left Shift 0 <= cnt <= 32 char cnt = tmp_imm & MASK003F; if (cnt > 32) { printf ("\nPSHA Dz,#Imm,Dz Error! #Imm=%7X exceed range.\n", tmp_imm); exit (); }
DSP_ALU_DST = DSP_ALU_SRC1 << cnt;
DSP_ALU_DSTG = ((DSP_ALU_SRC1G << cnt)
| (DSP_ALU_SRC1 >> (32 - cnt))) & MASK000000FF;
carry_bit = (DSP_ALU_DSTG & MASK00000001) == 0x1;
} else { // Right Shift 0 < cnt <= 32 char cnt = (~tmp_imm & MASK003F) + 1; if (cnt > 32) { printf ("\nPSHA Dz,#Imm,Dz Error! #Imm=%7X exceed range.\n", tmp_imm); exit (); }
if ((cnt > 8) && DSP_ALU_SRC1G_BIT7)
{
// MSB copy
DSP_ALU_DST = (DSP_ALU_SRC1 >> 8) | (DSP_ALU_SRC1G << (32 - 8));
DSP_ALU_DST = (long)DSP_ALU_DST >> (cnt - 8);
}
else
DSP_ALU_DST = (DSP_ALU_SRC1 >> cnt) | (DSP_ALU_SRC1G << (32 - cnt));
DSP_ALU_DSTG_LSB8 = (char)DSP_ALU_SRC1G_LSB8 >> cnt--;
carry_bit = ((DSP_ALU_SRC1 >> cnt) & MASK00000001) == 0x1;
}
overflow_bit = ! (POS_NOT_OV || NEG_NOT_OV);
#include "fixed_pt_overflow_protection.c" #include "fixed_pt_unconditional_update.c" #include "shift_dc_bit.c" }
DSP
pshl Sx,Sy,Dz
If Sy >= 0: Sx << Sy -> Dz, clear LSW of Dz If Sy < 0: Sx >> Sy -> Dz, clear LSW of Dz
111110********** 10000001xxyyzzzz
Update
1
1
Description
Logically shifts the top word contents of the Sx operand, stores the result in the top word of the Dz operand, and clears the bottom word of the Dz operand with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The amount of the shift is specified by the Sy operand. When the shift amount is positive, it shifts left. When the shift amount is negative, it shifts right. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void pshl (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; break;
case 0x1: DSP_ALU_SRC1 = X1; break;
case 0x2: DSP_ALU_SRC1 = A0; break;
case 0x3: DSP_ALU_SRC1 = A1; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0 & MASK003F0000; break;
case 0x1: DSP_ALU_SRC2 = Y1 & MASK003F0000; break;
case 0x2: DSP_ALU_SRC2 = M0 & MASK003F0000; break;
case 0x3: DSP_ALU_SRC2 = M1 & MASK003F0000; break; }
if ((DSP_ALU_SRC2_HW & MASK0020) == 0) { // Left Shift 0 <= cnt <= 16 char cnt = DSP_ALU_SRC2_HW & MASK001F; if (cnt > 16) { printf ("\nPSHL Sx,Sy,Dz Error! Shift %2X exceed range.\n", cnt); exit (); } DSP_ALU_DST_HW = DSP_ALU_SRC1_HW << cnt--; carry_bit = ((DSP_ALU_SRC1_HW << cnt) & MASK8000) == 0x8000; } else { // Right Shift 0 < cnt <= 16 char cnt = (~DSP_ALU_SRC2_HW & MASK000F) + 1; if (cnt > 16) { printf ("\nPSHL Sx,Sy,Dz Error! Shift -%2X exceed range.\n", cnt); exit (); }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW >> cnt--;
carry_bit = ((DSP_ALU_SRC1_HW >> cnt) & MASK0001) == 0x1;
}
DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // clear Guard bits else if (ex2_dz_no == 1) A1G = 0x0;
negative_bit = DSP_ALU_DST_MSB; zero_bit = DSP_ALU_DST_HW == 0; overflow_bit = 0x0;
#include "shift_dc_bit.c" }
DSP
dct pshl Sx,Sy,Dz
If DC = 1 & Sy >= 0: Sx << Sy -> Dz, clear LSW of Dz If DC = 1 & Sy < 0: Sx >> Sy -> Dz, clear LSW of Dz If DC = 0: nop
111110********** 10000010xxyyzzzz
1
1
Description
Conditionally logically shifts the top word contents of the Sx operand, stores the result in the top word of the Dz operand, and clears the bottom word of the Dz operand with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The amount of the shift is specified by the Sy operand. When the shift amount is positive, it shifts left. When the shift amount is negative, it shifts right. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits are not updated.
Operation
void pshl_dct { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; break;
case 0x1: DSP_ALU_SRC1 = X1; break;
case 0x2: DSP_ALU_SRC1 = A0; break;
case 0x3: DSP_ALU_SRC1 = A1; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0 & MASK003F0000; break;
case 0x1: DSP_ALU_SRC2 = Y1 & MASK003F0000; break;
case 0x2: DSP_ALU_SRC2 = M0 & MASK003F0000; break;
case 0x3: DSP_ALU_SRC2 = M1 & MASK003F0000; break; }
if ((DSP_ALU_SRC2_HW & MASK0020) == 0) { // Left Shift 0 <= cnt <= 16 char cnt = DSP_ALU_SRC2_HW & MASK001F; if (cnt > 16) { printf ("\nPSHL Sx,Sy,Dz Error! Shift %2X exceed range.\n", cnt); exit (); } DSP_ALU_DST_HW = DSP_ALU_SRC1_HW << cnt--; carry_bit = ((DSP_ALU_SRC1_HW << cnt) & MASK8000) == 0x8000; } else { // Right Shift 0 < cnt <= 16 char cnt = (~DSP_ALU_SRC2_HW & MASK000F) + 1; if (cnt > 16) { printf ("\nPSHL Sx,Sy,Dz Error! Shift -%2X exceed range.\n", cnt); exit (); }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW >> cnt--;
carry_bit = ((DSP_ALU_SRC1_HW >> cnt) & MASK0001) == 0x1;
}
if (DC == 1) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // clear Guard bits else if (ex2_dz_no == 1) A1G = 0x0; } }
DSP
dcf pshl Sx,Sy,Dz
If DC = 0 & Sy >= 0: Sx << Sy -> Dz, clear LSW of Dz If DC = 0 & Sy < 0: Sx >> Sy -> Dz, clear LSW of Dz If DC = 1: nop
111110********** 10000011xxyyzzzz
1
1
Description
Conditionally logically shifts the top word contents of the Sx operand, stores the result in the top word of the Dz operand, and clears the bottom word of the Dz operand with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The amount of the shift is specified by the Sy operand. When the shift amount is positive, it shifts left. When the shift amount is negative, it shifts right. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits are not updated.
Operation
void pshl_dcf (void) { switch (EX2_SX) { case 0x0: DSP_ALU_SRC1 = X0; break;
case 0x1: DSP_ALU_SRC1 = X1; break;
case 0x2: DSP_ALU_SRC1 = A0; break;
case 0x3: DSP_ALU_SRC1 = A1; break; }
switch (EX2_SY) { case 0x0: DSP_ALU_SRC2 = Y0 & MASK003F0000; break;
case 0x1: DSP_ALU_SRC2 = Y1 & MASK003F0000; break;
case 0x2: DSP_ALU_SRC2 = M0 & MASK003F0000; break;
case 0x3: DSP_ALU_SRC2 = M1 & MASK003F0000; break; }
if ((DSP_ALU_SRC2_HW & MASK0020) == 0) { // Left Shift 0 <= cnt <= 16 char cnt = DSP_ALU_SRC2_HW & MASK001F; if (cnt > 16) { printf ("\nPSHL Sx,Sy,Dz Error! Shift %2X exceed range.\n", cnt); exit (); } DSP_ALU_DST_HW = DSP_ALU_SRC1_HW << cnt--; carry_bit = ((DSP_ALU_SRC1_HW << cnt) & MASK8000) == 0x8000; } else { // Right Shift 0 < cnt <= 16 char cnt = (~DSP_ALU_SRC2_HW & MASK000F) + 1; if (cnt > 16) { printf ("\nPSHL Sx,Sy,Dz Error! Shift -%2X exceed range.\n", cnt); exit (); }
DSP_ALU_DST_HW = DSP_ALU_SRC1_HW >> cnt--;
carry_bit = ((DSP_ALU_SRC1_HW >> cnt) & MASK0001) == 0x1;
}
if (DC == 0) { DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // clear Guard bits else if (ex2_dz_no == 1) A1G = 0x0; } }
DSP
pshl #imm,Dz
If imm >= 0: Dz << imm -> Dz, clear LSW of Dz If imm < 0: Dz >> imm, clear LSW of Dz
111110********** 00010iiiiiiizzzz
Update
1
1
Description
Logically shifts the top word contents of the Dz operand, stores the result in the top word of the Dz operand, and clears the bottom word of the Dz operand with zeros. When Dz is a register that has guard bits, the guard bits are also zeroed. The amount of the shift is specified by the immediate value. When the shift amount is positive, it shifts left. When the shift amount is negative, it shifts right. The DC bit of the DSR register is updated according to the specifications for the CS bits. The N, Z, V, and GT bits of the DSR register are also updated.
Operation
void pshl_imm (void) { unsigned short tmp_imm; DSP_ALU_SRC1 = DSP_REG[ex2_dz_no]; switch (ex2_dz_no) { case 0x0: DSP_ALU_SRC1G = A0G; break;
case 0x1: DSP_ALU_SRC1G = A1G; break;
default: if (DSP_ALU_SRC1_MSB) DSP_ALU_SRC1G = 0xFF; else DSP_ALU_SRC1G = 0x0; }
tmp_imm = ((EX2_LW >> 4) & MASK0000003F); // bit[9:4] if ((tmp_imm & MASK0020) == 0) { // Left Shift 0 <= cnt < 16 char cnt = tmp_imm & MASK001F; if (cnt > 16) { printf ("\nPSHL Dz,#Imm,Dz Error! #Imm=%6X exceed range.\n", tmp_imm); exit (); } DSP_ALU_DST_HW = DSP_ALU_SRC1_HW << cnt--; carry_bit = ((DSP_ALU_SRC1_HW << cnt) & MASK8000) == 0x8000; } else { // Right Shift 0 < cnt <= 16 char cnt = (~tmp_imm & MASK001F) + 1; if (cnt > 16) { printf ("\nPSHL Dz,#Imm,Dz Error! #Imm=%6X exceed range.\n", tmp_imm); exit (); } DSP_ALU_DST_HW = DSP_ALU_SRC1_HW >> cnt--; carry_bit = ((DSP_ALU_SRC1_HW >> cnt) & MASK0001) == 0x1; }
DSP_REG_WD[ex2_dz_no2] = DSP_ALU_DST_HW; DSP_REG_WD[ex2_dz_no2+1] = 0x0; // clear LSW if (ex2_dz_no == 0) A0G = 0x0; // clear Guard bits else if (ex2_dz_no == 1) A1G = 0x0;
negative_bit = DSP_ALU_DST_MSB; zero_bit = DSP_ALU_DST_HW == 0; overflow_bit = 0x0;
#include "shift_dc_bit.c" }
DSP System Control Instructions
DSP
plds Dz,MACH
Dz -> MACH
111110********** 111011010000zzzz
1
1
Description
Stores the Dz operand in the MACH register. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Though PSTS, MOVX, and MOVY can be designated in parallel, their execution may take two cycles.
Operation
void plds_mach (void) { MACH = DSP_REG[ex2_dz_no]; }
DSP
plds Dz,MACL
Dz -> MACL
111110********** 111111010000zzzz
1
1
Description
Stores the Dz operand in the MACL register. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Though PSTS, MOVX, and MOVY can be designated in parallel, their execution may take two cycles.
Operation
void plds_macl (void) { MACL = DSP_REG[ex2_dz_no]; }
DSP
dct plds Dz,MACH
If DC = 1: Dz -> MACH Else: nop
111110********** 111011100000zzzz
1
1
Description
Conditionally stores the Dz operand in the MACH register. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Though PSTS, MOVX, and MOVY can be designated in parallel, their execution may take two cycles.
Operation
void plds_mach_dct (void) { if (DC == 1) MACH = DSP_REG[ex2_dz_no]; }
DSP
dct plds Dz,MACL
If DC = 1: Dz -> MACL Else: nop
111110********** 111111100000zzzz
1
1
Description
Conditionally stores the Dz operand in the MACL register. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Though PSTS, MOVX, and MOVY can be designated in parallel, their execution may take two cycles.
Operation
void plds_macl_dct (void) { if (DC == 1) MACL = DSP_REG[ex2_dz_no]; }
DSP
dcf plds Dz,MACH
If DC = 0: Dz -> MACH Else: nop
111110********** 111011110000zzzz
1
1
Description
Conditionally stores the Dz operand in the MACH register. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Though PSTS, MOVX, and MOVY can be designated in parallel, their execution may take two cycles.
Operation
void plds_mach_dcf (void) { if (DC == 0) MACH = DSP_REG[ex2_dz_no]; }
DSP
dcf plds Dz,MACL
If DC = 0: Dz -> MACL Else: nop
111110********** 111111110000zzzz
1
1
Description
Conditionally stores the Dz operand in the MACL register. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Though PSTS, MOVX, and MOVY can be designated in parallel, their execution may take two cycles.
Operation
void plds_macl_dcf (void) { if (DC == 0) MACL = DSP_REG[ex2_dz_no]; }
DSP
psts MACH,Dz
MACH -> Dz
111110********** 110011010000zzzz
1
1
Description
Stores the contents of the MACH register in the Dz operand. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Though PSTS, MOVX and MOVY can be designated in parallel, their execution may take 2 cycles.
Operation
void psts_mach (void) { DSP_REG[ex2_dz_no] = MACH; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G |= MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G |= MASKFFFFFF00; } }
DSP
psts MACL,Dz
MACL -> Dz
111110********** 110111010000zzzz
1
1
Description
Stores the contents of the MACL register in the Dz operand. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Though PSTS, MOVX and MOVY can be designated in parallel, their execution may take 2 cycles.
Operation
void psts_macl (void) { DSP_REG[ex2_dz_no] = MACL; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G |= MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G |= MASKFFFFFF00; } }
DSP
dct psts MACH,Dz
If DC = 1: MACH -> Dz Else: nop
111110********** 110011100000zzzz
1
1
Description
Conditionally stores the contents of the MACH register in the Dz operand. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Though PSTS, MOVX and MOVY can be designated in parallel, their execution may take 2 cycles.
Operation
void psts_mach_dct (void) { if (DC == 1) { DSP_REG[ex2_dz_no] = MACH; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G |= MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G |= MASKFFFFFF00; } } }
DSP
dct psts MACL,Dz
If DC = 1: MACL -> Dz Else: nop
111110********** 110111100000zzzz
1
1
Description
Conditionally stores the contents of the MACL register in the Dz operand. The instruction is executed if the DC bit is set to 1. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Though PSTS, MOVX and MOVY can be designated in parallel, their execution may take 2 cycles.
Operation
void psts_macl_dct (void) { if (DC == 1) { DSP_REG[ex2_dz_no] = MACL; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G |= MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G |= MASKFFFFFF00; } } }
DSP
dcf psts MACH,Dz
If DC = 0: MACH -> Dz Else: nop
111110********** 110011110000zzzz
1
1
Description
Conditionally stores the contents of the MACH register in the Dz operand. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Though PSTS, MOVX and MOVY can be designated in parallel, their execution may take 2 cycles.
Operation
void psts_mach_dcf (void) { if (DC == 0) { DSP_REG[ex2_dz_no] = MACH; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G |= MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G |= MASKFFFFFF00; } } }
DSP
dcf psts MACL,Dz
If DC = 0: MACL -> Dz Else: nop
111110********** 110111110000zzzz
1
1
Description
Conditionally stores the contents of the MACL register in the Dz operand. The instruction is executed if the DC bit is set to 0. The DC, N, Z, V, and GT bits of the DSR register are not updated.
Note
Though PSTS, MOVX and MOVY can be designated in parallel, their execution may take 2 cycles.
Operation
void psts_macl_dcf (void) { if (DC == 0) { DSP_REG[ex2_dz_no] = MACL; if (ex2_dz_no == 0) { A0G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A0G |= MASKFFFFFF00; } else if (ex2_dz_no == 1) { A1G = DSP_ALU_DSTG & MASK000000FF; if (DSP_ALU_DSTG_BIT7) A1G |= MASKFFFFFF00; } } }