RISC-Vのオペコードは、取り揃えはおそらくMIPSをベースにしているが、その命令フォーマットはMIPSのそれとは異なっている。 一応、彼らの言い分としてはデコードのしやすさを基準に設計してあるらしいが、それが本当に有用かどうかは正直分からない。
特に、即値をとるフィールドについてはちょっとした小細工がしてあり、これもMIPSのそれとは異なっている。
Loadの即値はまだマシなのだが、Storeの即値は2つに分かれている。 これにより、レジスタフィールドを崩すことなく、即値の場所を切り替えるだけでLoad側とデコード回路を共通化できるらしい。。。が、それがHWの軽減にどこまで貢献できるかはわからない。
で、即値のフィールドが分かれているので、自作ISSでは、デコードテーブルを作るために一応バーで区切っていた。 が、だからと言って特殊な措置をしていたのではなく、単純にそのまま表示していたのでトレースデータが分かりにくかった。
$arch_table[ 15] = Array['sb d[19:15],d[24:20],h[31:25]|d[11:7]', 'XXXXX', 'XX', $arch_table[ 16] = Array['sh d[19:15],d[24:20],h[31:25]|d[11:7]', 'XXXXX', 'XX', $arch_table[ 17] = Array['sw d[19:15],d[24:20],h[31:25]|d[11:7]', 'XXXXX', 'XX',
トレースデータは以下の様になる。
39:M:MBar:[80002040][P80002040] 04e10513 : addi r10,r02,0x04e r02=>7f003f78 r10<=7f003fc6 40:M:MBar:[80002044][P80002044] 08112623 : sw r02,r01,0x04|r12 r02=>7f003f78 r01=>00000290 (7f004004)<=00000290 41:M:MBar:[80002048][P80002048] 08812423 : sw r02,r08,0x04|r08 r02=>7f003f78 r08=>80002034 (7f004000)<=80002034 42:M:MBar:[8000204c][P8000204c] 08912223 : sw r02,r09,0x04|r04 r02=>7f003f78 r09=>00000000 (7f003ffc)<=00000000 43:M:MBar:[80002050][P80002050] 09212023 : sw r02,r18,0x04|r00 r02=>7f003f78 r18=>00000000 (7f003ff8)<=00000000 44:M:MBar:[80002054][P80002054] 07312e23 : sw r02,r19,0x03|r28 r02=>7f003f78 r19=>00000000 (7f003ff4)<=00000000
さすがにちょっと格好悪い。
そこで、バーがついたときは前後のフィールドを接合するように実装を変更した。
if bit_field.match(/\w+\[\d+:\d+\]\|/) then inst_operand_c_fp.printf(" inst_operand[%s].connect[%d] = 1;\n", inst_name, op_index) else inst_operand_c_fp.printf(" inst_operand[%s].connect[%d] = 0;\n", inst_name, op_index) end
最後にバーが入っていると、後続のオペランドと接続するという情報を付け加える。これをもとに、トレースデータを作成する。
if (inst_str[0] == '@') { - uint32_t msb_bit = inst_operand[inst_idx].msb_lst[replace_idx]; - uint32_t lsb_bit = inst_operand[inst_idx].lsb_lst[replace_idx]; - operandType type = inst_operand[inst_idx].type_lst[replace_idx]; - uint32_t length_field = msb_bit - lsb_bit + 1; + uint32_t length_field = 0; + operandType type; + uint32_t operand_bit = 0; + do { + uint32_t msb_bit = inst_operand[inst_idx].msb_lst[replace_idx]; + uint32_t lsb_bit = inst_operand[inst_idx].lsb_lst[replace_idx]; + type = inst_operand[inst_idx].type_lst[replace_idx]; + length_field = length_field + (msb_bit - lsb_bit + 1); + operand_bit = (operand_bit << (msb_bit - lsb_bit + 1)) | ExtractBitField (inst_hex, msb_bit, lsb_bit); + replace_idx++; + } while ((replace_idx <= inst_operand[inst_idx].size) && + (inst_operand[inst_idx].connect[replace_idx-1] != 0));
inst_operand.connectが1になっていると、後続のフィールドと接続して、operand_bitを拡張する。
その結果、一応以下の様にちゃんとしたトレースデータが出力されるようになった。
40:M:MBar:[80002044][P80002044] 08112623 : sw r02,0x08c(r01) r02=>7f003f78 r01=>00000290 (7f004004)<=00000290 41:M:MBar:[80002048][P80002048] 08812423 : sw r02,0x088(r08) r02=>7f003f78 r08=>80002034 (7f004000)<=80002034 42:M:MBar:[8000204c][P8000204c] 08912223 : sw r02,0x084(r09) r02=>7f003f78 r09=>00000000 (7f003ffc)<=00000000 43:M:MBar:[80002050][P80002050] 09212023 : sw r02,0x080(r18) r02=>7f003f78 r18=>00000000 (7f003ff8)<=00000000 44:M:MBar:[80002054][P80002054] 07312e23 : sw r02,0x07c(r19) r02=>7f003f78 r19=>00000000 (7f003ff4)<=00000000 45:M:MBar:[80002058][P80002058] 07412c23 : sw r02,0x078(r20) r02=>7f003f78 r20=>00000000 (7f003ff0)<=00000000 46:M:MBar:[8000205c][P8000205c] 07512a23 : sw r02,0x074(r21) r02=>7f003f78 r21=>00000000 (7f003fec)<=00000000 47:M:MBar:[80002060][P80002060] 07612823 : sw r02,0x070(r22) r02=>7f003f78 r22=>00000000 (7f003fe8)<=00000000 48:M:MBar:[80002064][P80002064] 07712623 : sw r02,0x06c(r23) r02=>7f003f78 r23=>00000000 (7f003fe4)<=00000000