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<<OP(31))) != 0 | ||
QBBC LABEL, REG1, OP(31) | Quick Branch if Bit is Clear | Jump to LABEL if (REG1 & (1<<OP(31))) == 0 | ||
WBS REG1, OP(31) | Wait Until Bit Set | QBBC $, REG1, OP(31) に相当 | ||
WBC REG1, OP(31) | Wait Until Bit Clear | QBBS $, REG1, OP(31) に相当 | ||
HALT | Halt Operation | PRU実行停止 (Instruction PointerはHALT命令の場所で停止、復帰後はその場所のフェッチから再開) | ||
SLP IM(1) | Sleep Operation | PRU動作クロック停止 IM(1)==0の場合、リセットするまで復帰しない。 IM(1)==1の場合、イベントが発生すると復帰する。 | ||
LOOP LABEL, OP(256) | Hardware Loop Assist | 本命令の直後からLABELの直前までをOP(256)回ループ実行する | ||
ILOOP LABEL, OP(256) | Hardware Loop Assist (Interruptible) | LOOPと同じだが、外部からのbreakができるらしい?(詳細不明) |