2016-06-15 5 views
0

私はSPARC T1 RTLコードで実行されるSPARCアセンブリファイルを持っています(それをメモリイメージに変換するアセンブラを介して)。しかし、私はRTLによって何命令が実行されているのか知る必要があります。ファイル内の命令数を手動で数えることはできません。コードの最初の数行を https://dl.dropboxusercontent.com/u/48635184/exu_muldiv.sアセンブリファイル内の命令数を計算する

しかし、ここにある:あなたがこれを行うには、私の道を示すことができれば私は非常に

ファイルが大きいので

が、私はDropboxのリンクを添付しています...感謝します:

/*********************************************************************** 
* Name: exu_muldiv.s 
* Date: April 23, 2003 
* 
* Description: Execute Mulx, Mulscc, Smul, Smulcc, Umul, Umulcc, 
* Sdiv, Sdivcc, Sdivx, Udiv, Udivcc, Udivx with interesting data 
* patterns in multiple threads. Also play with delay slots and 
* intermixed mul and div operations. 
* 
* This test depends on SAS for result checking.  
* 
**********************************************************************/ 

! be sure to update when adding cases... 
#define NUM_MUL_CASES 6 
#define NUM_DIV_CASES 4 
#define NUM_IMMED_CASES 5  

! for divide by zero cases 
#define H_T0_Division_By_Zero 
#define My_T0_Division_By_Zero \ 
rdpr %tstate, %i1; \ 
rdpr %tt, %i1; \ 
rdpr %tpc, %i0; \ 
rdpr %tnpc, %i1; \ 
done; \ 
nop;  

/*******************************************************/  
#include "boot.s" 

.global main 
main: 
th_fork(th_main,%l0)  ! start up to four threads. 
    ! All threads do the same thing, but with different data patterns. 
    ! No need to run more than one core. 
th_main_0: 
    setx mul_data_t0,%g7,%g1 
     ba all_threads1 
    nop 

th_main_1: 
     setx mul_data_t1,%g7,%g1 
    ba all_threads1 
    nop 

th_main_2: 
    setx mul_data_t2,%g7,%g1 
     ba all_threads1 
    nop 

th_main_3: 
    setx mul_data_t3,%g7,%g1 
    ba all_threads1 
    nop 

all_threads1:  
    !************************************************************* 
    ! Operand2 as a register: MULX, UMUL, SMUL, UMULcc, SMULcc 
    !************************************************************* 
    add %g0,NUM_MUL_CASES,%g2 
    mova %icc,%g1,%g3  ! keep the multiply operand address handy 

mul_loop1: 
    ldx [%g1],%l1 
    ldx [%g1+8],%l2 
    wr %g0,%g0,%ccr  ! ccr clear 

    mulx %l1,%l2,%l4 
    umul %l1,%l2,%l5 
    rd %y,%i1   ! be sure SAS looks at Y-reg 
    smul %l1,%l2,%l6 
    rd %y,%i1 

     wr %g0,%g0,%ccr  ! clear ccr  
    umulcc %l1,%l2,%l7  
    rd %y,%i1 
     wr %g0,%g0,%ccr   
    smulcc %l1,%l2,%l6  
    rd %y,%i1 

     wr %g0,0xff,%ccr  ! set ccr. Should not matter.  
    umulcc %l1,%l2,%l7  
    rd %y,%i1 
     wr %g0,0xff,%ccr  
    smulcc %l1,%l2,%l6  
    rd %y,%i1  

    sub %g2,0x1,%g2 
    brnz,pt %g2,mul_loop1 
    add %g1,0x10,%g1  ! move operand pointer 

    !********************************** 
    ! Operand2 as a register: MULScc 
    !********************************** 
#ifndef MULSCC_BUGS  
     mova %icc,%g3,%g1  ! same ops as mul_loop1 
    add %g0,NUM_MUL_CASES,%g2  
mulscc_1: 
    wr %g0,%g0,%ccr  ! ccr clear  
    ldx [%g1],%l1 
    ldx [%g1+8],%l2 
    wr %l1,0,%y  ! lower bits of multiplier into Y-reg 
    rd %y,%l0   ! for sas debug 
    srl %l1,0,%l1  ! clear rs1 upper 
    srl %l2,0,%l2  ! clear rs2 upper 
    mulx %l1,%l2,%l4  ! save for later compare 
    add %g0,0,%l1  ! clear rs1 (product upper) completely 

    add %g0,32,%l3  ! bit position counter 
mulscc_2: 
    sub %l3,1,%l3 
    mulscc %l1,%l2,%l1 
    brgez,pt %l3,mulscc_2 
    nop 

    sllx %l1,33,%l1  ! product upper 
    rd %y,%l3   ! product lower 
    or %l1,%l3,%l3  ! full product should be equal to mulx 
    subcc %l3,%l4,%l5 
    tnz T_BAD_TRAP 
    nop 

    sub %g2,0x1,%g2 
    brnz,pt %g2,mulscc_1 
    add %g1,0x10,%g1  ! move operand pointer 
#endif  

    !**************************************** 
    ! Operand2 as a register: SDIVX, UDIVX 
    !**************************************** 
    rdth_id    ! get thid in %o1 
    cmp %o1,0 
    be th_divx_0 
    cmp %o1,1 
    be th_divx_1 
    cmp %o1,2 
    be th_divx_2 
    nop 
    ba th_divx_3  ! if there are more than 4 threads... 
    nop 

th_divx_0: 
    setx divx_data_t0,%g7,%g1 
     ba all_threads2 
    nop 

th_divx_1: 
    setx divx_data_t1,%g7,%g1 
     ba all_threads2 
    nop 

th_divx_2: 
    setx divx_data_t2,%g7,%g1 
     ba all_threads2 
    nop 

th_divx_3: 
    setx divx_data_t3,%g7,%g1 
    ba all_threads2 
    nop 

all_threads2:  
    add %g0,NUM_DIV_CASES,%g2 

divx_loop1: 
    ldx [%g1],%l1 
    ldx [%g1+8],%l2 
    wr %g0,%g0,%ccr  ! ccr clear 

    sdivx %l1,%l2,%l3 
    udivx %l1,%l2,%l4 
    sdivx %l2,%l1,%l5  ! use each operand as divisor and dividend 
    udivx %l2,%l1,%l6 

    sub %g2,0x1,%g2 
    brnz,pt %g2,divx_loop1 
    add %g1,0x10,%g1  ! move operand pointer 
+1

あなたがエミュレータをハックして実行する命令の数を与えることができるかどうか疑問に思っています(これが非理想的なら私を許してください) – Leo

+0

動的命令数(実行された命令の総数) 、静的なinsnカウント(ファイル内のinsnの総数ではなく、insn内部のループはまだ1回だけカウントされます。つまりcode-size)? –

+1

@Leo、あなたはそうです、私はVCS Simulatorで実行していますが、どうやってそれをやるべきか分かりません。 – user3285014

答えて

1

私は、一般的に、動的命令数を知るための唯一の方法は、実際に指示をカウントインストルメント環境でコードを実行することだと思います。 (例えば、シミュレータまたはパーフォーマンスカウンタを備えたCPU)。

私は、別のプログラムが実行される命令の数を確実に計算できるプログラムは、Halting Problemを解決することと同等であると思います。

多くの実用的なケースでは、ループの後の分岐はループによって計算された結果に依存しません。ループ終了条件が単純である場合、カウンタを上限までインクリメントするのと同じように、iterations * per-iterを合計に追加して移動するだけで済みます。

これはではなく、という単純な問題です。複雑さはおそらく、asmをその入力とする最適化コンパイラを書くことに似ています。どのブランチが採用されるかを把握するために、データフローを分析する必要があります。また、コードによっては、何が起こるかをシミュレートするだけで済みます。

ほとんどの場合、ほぼ確実に@Leoのようなシミュレータ/エミュレータが見つかります。

+0

私には分かりませんでした。 – Leo