====== TI Sitara PRU (Programmable Real-time Unit) ====== TIのSitaraシリーズの一部には、PRUという32-bit RISCマイコンが2つ搭載されている。 メインプロセッサのARMとは独立して動作し、リアルタイム性の高い処理を実行するのに使うことができる。 詳しくは資料 SPRUHF8A を見ると良い。 ここでは上記資料のうち、命令セットなどを一覧できるようにして整理したものを掲載する。 ===== テーブル内の表記 ===== ^表記^意味^例^ |REG, REG1, REG2, ...|レジスタの8/16/32-bit領域| r0\\ r1.w0\\ r3.b2 | |Rn, Rn1, Rn2, ...|レジスタ(32-bit全体のみ)| r0\\ r1 | |Rn.tx|レジスタのうち特定の1ビット| r0.t23\\ r1.b1.t4 | |Cn, Cn1, Cn2, ...|32-bit定数テーブルの要素| c0\\ c1 | |bn|??r0のb0,b1,b2,b3のどれか| b0 | |LABEL|ジャンプラベル。\\ 丸括弧を付けてもよい。\\ 定数値でもよい。| loop1\\ (loop1)\\ 0 | |IM(n)|定数値。\\ 先頭にシャープを付けてもよい。\\ コンパイル時に定数になれば式でもよい。\\ ラベルやレジスタアドレスでもよい。| #23\\ 0b0110\\ 2+2\\ &r3.w2 | |OP(n)|REGとIM(n)の組み合わせ| r0\\ r1.w0\\ #0x7f\\ 1<<3\\ loop1\\ &r1.w0 | ===== 命令セット ===== ^ カテゴリ ^ 命令 ^ 説明 ^ 動作 ^ サイクル数 ^ | 算術 | ADD REG1, REG2, OP(255) | Unsigned Integer Add | REG1 = REG2 + OP(255)\\ %%carry = (( REG2 + OP(255) ) >> bitwidth(REG1)) & 1%% | | | ::: | ADC REG1, REG2, OP(255) | Unsigned Integer Add with Carry | REG1 = REG2 + OP(255) + carry\\ %%carry = (( REG2 + OP(255) + carry ) >> bitwidth(REG1)) & 1%% | | | ::: | SUB REG1, REG2, OP(255) | Unsigned Integer Subtract | REG1 = REG2 - OP(255)\\ %%carry = (( REG2 - OP(255) ) >> bitwidth(REG1)) & 1%% | | | ::: | SUC REG1, REG2, OP(255) | Unsigned Integer Subtract with Carry | REG1 = REG2 - OP(255) - carry\\ %%carry = (( REG2 - OP(255) - carry ) >> bitwidth(REG1)) & 1%% | | | ::: | RSB REG1, REG2, OP(255) | Reverse Unsigned Integer Subtract | REG1 = OP(255) - REG2\\ %%carry = (( OP(255) - REG2 ) >> bitwidth(REG1)) & 1%% | | | ::: | RSC REG1, REG2, OP(255) | Reverse Unsigned Integer Subtract with Carry | REG1 = OP(255) - REG2 - carry\\ %%carry = (( OP(255) - REG2 - carry ) >> bitwidth(REG1)) & 1%% | | | 論理 | LSL REG1, REG2, OP(31) | Logical Shift Left | %%REG1 = REG2 << (OP(31) & 0x1f)%% | | | ::: | LSR REG1, REG2, OP(31) | Logical Shift Right | %%REG1 = REG2 >> (OP(31) & 0x1f)%% | | | ::: | AND REG1, REG2, OP(255) | Bitwise AND | REG1 = REG2 & OP(255) | | | ::: | OR REG1, REG2, OP(255) | Bitwise OR | REG1 = REG2 %%|%% OP(255) | | | ::: | XOR REG1, REG2, OP(255) | Bitwise XOR | REG1 = REG2 %%^%% OP(255) | | | ::: | NOT REG1, REG2 | Bitwise NOT | REG1 = ~REG2 | | | 算術 | MIN REG1, REG2, OP(255) | Copy Minimum | REG1 = (REG2 < OP(255)) ? REG2 : OP(255) | | | ::: | MAX REG1, REG2, OP(255) | Copy Maximum | REG1 = (REG2 > OP(255)) ? REG2 : OP(255) | | | 論理 | CLR REG1, REG2, OP(31) | Clear Bit | %%REG1 = REG2 & ~(1 << (OP(31) & 0x1f))%% | | | ::: | CLR REG1, OP(31) | ::: | %%REG1 &= ~(1 << (OP(31) & 0x1f))%% | | | ::: | CLR REG1, Rn.tx | ::: | REG1 = Rn & ~Rn.tx | | | ::: | CLR Rn.tx | ::: | Rn &= ~Rn.tx | | | ::: | SET REG1, REG2, OP(31) | Set Bit | %%REG1 = REG2 | (1 << (OP(31) & 0x1f))%% | | | ::: | SET REG1, OP(31) | ::: | %%REG1 |= (1 << (OP(31) & 0x1f))%% | | | ::: | SET REG1, Rn.tx | ::: | REG1 = Rn %%|%% Rn.tx | | | ::: | SET Rn.tx | ::: | Rn %%|%%= Rn.tx | | | 特殊 | LMBD REG1, REG2, OP(255) | Left-Most Bit Detect | OP(255)&1が0の場合 → REG1 = CountLeadingOnes(REG2)\\ OP(255)&1が1の場合 → REG1 = CountLeadingZeros(REG2) | | | ::: | NOPn REG1, REG2, OP(255) | NULL Operation | 何もしない or 実装依存の動作 | | | | | | | | | 転送 | MOV REG1, OP(0xFFFFFFFF) | Copy Value | REG1 = OP(0xFFFFFFFF)\\ ただしOPが即値の場合、LDIまたはLDI×2個に変換される | | | ::: | LDI REG1, IM(65535) | Load Immediate | REG1 = IM(65535) | | | ::: | MVIB [*][&][--]REG1[++], [*][&][--]REG2[++]\\ MVIW [*][&][--]REG1[++], [*][&][--]REG2[++]\\ MVID [*][&][--]REG1[++], [*][&][--]REG2[++] | Move Register File Indirect | レジスタまたはレジスタポインタ間接での値のコピー。\\ ポインタの場合プリデクリメント/ポストインクリメントを付けられる。\\ 入力が命令の幅(B=8,W=16,D=32)より小さい場合はゼロ拡張される。\\ なおレジスタポインタはr1.b0, r1.b1, r1.b2, r1.b3のみが使用可能。 | | | ::: | LBBO [&]REG1, Rn2, OP(255), IM(124) | Load Byte Burst | memcpy( offset(REG1), Rn2+OP(255), IM(124) ) | | | ::: | LBBO [&]REG1, Rn2, OP(255), bn | ::: | memcpy( offset(REG1), Rn2+OP(255), bn ) | | | ::: | SBBO [&]REG1, Rn2, OP(255), IM(124) | Store Byte Burst | memcpy( Rn2+OP(255), offset(REG1), IM(124) ) | | | ::: | SBBO [&]REG1, Rn2, OP(255), bn | ::: | memcpy( Rn2+OP(255), offset(REG1), bn ) | | | ::: | LBCO [&]REG1, Cn2, OP(255), IM(124) | Load Byte Burst with Constant Table Offset | memcpy( offset(REG1), Cn2+OP(255), IM(124) ) | | | ::: | LBCO [&]REG1, Cn2, OP(255), bn | ::: | memcpy( offset(REG1), Cn2+OP(255), bn ) | | | ::: | SBCO [&]REG1, Cn2, OP(255), IM(124) | Store Byte Burst with Constant Table Offset | memcpy( Cn2+OP(255), offset(REG1), IM(124) ) | | | ::: | SBCO REG1, Cn2, OP(255), bn | ::: | memcpy( Cn2+OP(255), offset(REG1), bn ) | | | ::: | ZERO IM(123), IM(124) | Clear Register Space | memset( IM(123), 0, IM(124) ) | 1 | | ::: | ZERO ®1, IM(124) | ::: | memset( ®1, 0, IM(124) ) | 1 | | ::: | FILL IM(123), IM(124) | Fill Register Space | memset( IM(123), 0xFF, IM(124) ) | 1 | | ::: | FILL ®1, IM(124) | ::: | memset( ®1, 0xFF, IM(124) ) | 1 | | ::: | XIN IM(253), REG, IM(124) | Register Transfer In | SPP.SHIFT_EN==0の場合\\ memset( offset(REG), &Device[IM(253)] + offset(REG), IM(124) )\\ SPP.SHIFT_EN==1の場合\\ memset( offset(REG), &Device[IM(253)] + wrap(offset(REG) + R0.b0*4), IM(124) ) | 1\\ (ScratchPad) | | ::: | XIN IM(253), REG, bn | ::: | IM(124)をbnに読み替え | 1\\ (ScratchPad) | | ::: | XOUT IM(253), REG, IM(124) | Register Transfer Out | SPP.SHIFT_EN==0の場合\\ memset( &Device[IM(253)] + offset(REG), offset(REG), IM(124) )\\ SPP.SHIFT_EN==1の場合\\ memset( &Device[IM(253)] + wrap(offset(REG) + R0.b0*4), offset(REG), IM(124) ) | 1\\ (ScratchPad) | | ::: | XOUT IM(253), REG, bn | ::: | IM(124)をbnに読み替え | 1\\ (ScratchPad) | | ::: | XCHG IM(253), REG, IM(124) | Register Transfer Exchange | SPP.SHIFT_EN==0の場合\\ memset( temp, offset(REG), IM(124) )\\ memset( offset(REG), &Device[IM(253)] + offset(REG), IM(124) )\\ memset( &Device[IM(253)] + offset(REG), temp, IM(124) )\\ SPP.SHIFT_EN==1の場合\\ memset( temp, offset(REG), IM(124) )\\ memset( offset(REG), &Device[IM(253)] + wrap(offset(REG) + R0.b0*4), IM(124) )\\ memset( &Device[IM(253)] + wrap(offset(REG) + R0.b0*4), temp, IM(124) ) | 1\\ (ScratchPad) | | ::: | XCHG IM(253), REG, bn | ::: | IM(124)をbnに読み替え | 1\\ (ScratchPad) | | ::: | SXIN IM(253), REG, IM(124) | Register and Status Transfer In | XINのStatus転送あり版 (???) | | | ::: | SXIN IM(253), REG, bn | ::: | ::: | | | ::: | SXOUT IM(253), REG, IM(124) | Register and Status Transfer Out | XOUTのStatus転送あり版 (???) | | | ::: | SXOUT IM(253), REG, bn | ::: | ::: | | | ::: | SXCHG IM(253), REG, IM(124) | Register and Status Transfer Exchange | XCHGのStatus転送あり版 (???) | | | ::: | SXCHG IM(253), REG, bn | ::: | ::: | | | フロー | JMP OP(65535) | Unconditional Jump | PRU Instruction Pointer = OP(65535) | | | ::: | JAL REG1, OP(65535) | Unconditional Jump and Link | REG1 = Current PRU Instruction Pointer + 1\\ PRU Instruction Pointer = OP(65535) | | | ::: | CALL OP(65535) | Call Procedure | JAL r30.w0, OP(65535) に相当 | | | ::: | RET | Return from Procedure | JMP r30.w0 に相当 | | | ::: | QBGT LABEL, REG1, OP(255) | Quick Branch if Greater Than | Jump to LABEL if OP(255) > REG1 (※オペランドの並びに注意) | | | ::: | QBGE LABEL, REG1, OP(255) | Quick Branch if Greater Than or Equal | Jump to LABEL if OP(255) >= REG1 (※オペランドの並びに注意) | | | ::: | QBLT LABEL, REG1, OP(255) | Quick Branch if Less Than | Jump to LABEL if OP(255) < REG1 (※オペランドの並びに注意) | | | ::: | QBLE LABEL, REG1, OP(255) | Quick Branch if Less Than or Equal | Jump to LABEL if OP(255) <= REG1 (※オペランドの並びに注意) | | | ::: | QBEQ LABEL, REG1, OP(255) | Quick Branch if Equal | Jump to LABEL if OP(255) == REG1 | | | ::: | QBNE LABEL, REG1, OP(255) | Quick Branch if Not Equal | Jump to LABEL if OP(255) != REG1 | | | ::: | QBA LABEL | Quick Branch Always | Jump to LABEL | | | ::: | QBBS LABEL, REG1, OP(31) | Quick Branch if Bit is Set | %%Jump to LABEL if (REG1 & (1<