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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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:

For more information see the document "tnsh7456ae.pdf".

Operation

void SLEEP (void) { Sleep_standby(); }

Possible Exceptions

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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:

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:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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:

  1. Multiplies all terms. The results are 28 bits long.
  2. Aligns these results, rounding them to fit within 30 bits.
  3. Adds the aligned values.
  4. Performs normalization and rounding.

Special processing is performed in the following cases:

  1. If an input value is an sNaN, an invalid exception is generated.
  2. If the input values to be multiplied include a combination of 0 and infinity, an invalid exception is generated.
  3. In cases other than the above, if the input values include a qNaN, the result will be a qNaN.
  4. In cases other than the above, if the input values include infinity:
    1. If multiplication results in two or more infinities and the signs are different, an invalid exception will be generated.
    2. Otherwise, correct infinities will be stored.
  5. 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

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:

  1. Multiplies all terms. The results are 28 bits long.
  2. Aligns these results, rounding them to fit within 30 bits.
  3. Adds the aligned values.
  4. Performs normalization and rounding.

Special processing is performed in the following cases:

  1. If an input value is an sNaN, an invalid exception is generated.
  2. If the input values to be multiplied include a combination of 0 and infinity, an invalid operation exception is generated.
  3. In cases other than the above, if the input values include a qNaN, the result will be a qNaN.
  4. In cases other than the above, if the input values include infinity:
    1. If multiplication results in two or more infinities and the signs are different, an invalid exception will be generated.
    2. Otherwise, correct infinities will be stored.
  5. 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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; } } }