[SPARC] ビット処理演算

問題定義


ビット処理演算

0 から 63 までの数を格納する集合に対する演算を実装しようとする。 集合は静的領域に set1, set2, set3 という名前で定義する。set1, set2, set3 の各ビットは 63, 62, ... ,2, 1, 0 を表し、該当 する数が集合に属していればそのビットが 1 、そうでなければ 0 に指定される。 初期にはテストしようとする集合を定義すればよい。

  • member(j, set): j set の要素であれば 1 を返す。

  • union: 和集合。set3 = set1 ∪ set2

  • intersection: 積集合。set3 = set1 ∩ set2

  • subtract: 差集合。set3 = set1 - set2

  • add(j, set): 集合 set に要素 j を追加する。

  • mapinc(set,d): set の各要素に d を足した集合。 例えば set({1, 13, 17}, 1) = {2, 14, 18}

    である。

    提出物

  • 上記 3 つの関数のみが定義されているファイルを提出する。main と集合 set1, set2 が定義されるファイルは提出しない。 各自テストのために別途作成し、リンクして実行するのに使用する。


設計

1. 集合は静的領域に set1, set2, set3 という名前で定義。
2. set1, set2, set3 の各ビットは 63, 62, 61...., 2, 1, 0 を表す。
3. 該当する数が集合に属していればそのビットが 1、そうでなければ 0 に指定される。
4. 初期テストしようとする集合を定義。

< 取るに足らないソースコード.. >

1. member(j,set) 関数 > 結果値 0 or 1

*該当のソースコードを動かすには 太字のコメント を解除してください。 .

!.section ".data"

!set1:.word 1 , 4 , 5 , 16

!set2:.word 1 , 4 , 7 , 23

!

!.section ".text"

!!local variables

!n = -4


! index i in $l0

! max in $l1

!

!

.global main

!main :

save %sp, -96 ,%sp

!

set set1, %l2

!    st %l2,[%sp + 16 ]

!

set set2, %l3

!    st %l3,[%sp + 32 ]

!    mov 16 ,%o0

!    call member

!    mov %l2,%o1

!test :

ret

!

restore


!N= 4 ! ( if N = 4 , it 's only works in {a,b,c,d} just 4 objects)

.global member

member : save %sp, -96 ,%sp

mov 1 ,%l0 ! move 1 to l0

sll %l0,N,%l5 ! 2 ^N to l5 (this time 2 ^ 4 = 16 )

add %fp,%l5,%o3 ! address %fp +16

ld [%o3],%o0 ! right value of [%fp +16 ]

cmp %i0,%o0 ! x == [%fp +16 ] ?

be,a isexist ! if yes goto isexist return

ba loop ! or not goto loop

indexup : inc %l0 ! increase index ++

loop:   sll %l0, 2 ,%l2 ! address l2 = i* 4

add %o0,%l2,%o1 ! [%fp +16 +i* 4 ]

ld [%o1],%l1    ! load [%fp +16 +i* 4 ]

cmp %i0,%l1     ! x== [%fp +16 +i* 4 ]

be isexist      ! if equal then goto isexist

cmp %l0,N       ! %l0 < N

bl,a indexup    ! if true goto indexup

nop

nonexist: mov 0 ,%i0 ! return value 0 - not exist

ret

restore

isexist: mov 1 ,%i0 ! return value 1 - it 's exist

ret

restore



2. add(j,set) 関数 >  { 1,3,4, j }

*該当のソースコードを動かすには 太字のコメント を解除してください。 .

!.section ".data"

!set1:.word 1 , 4 , 5 , 16

!

!.section ".text"

!local variables

!n = -4

!

! index i in $l0

! max in $l1

!

!

.global main

!main :

save %sp, -96 ,%sp

!

set set1, %l2

!    mov 44 ,%o1

!    call add

!    mov %l2,%o0

!test :

ret

!

restore

!N= 4 ! ( if N = 4 , it 's only works in {a,b,c,d} just 4 objects)

.global add

add :    save %sp, -96 ,%sp

mov 1 ,%l0

mov %i0,%o0 ;

sll %l0,N,%l5 ! 2 ^N to l5 (this time 2 ^ 4 = 16 )

add %i0,%l5,%i0

st %i1,[%i0]

addend:     ret

restore


3. mapinc(set,d) 関数 >  {1,3,4} , d= 1 > {2,4,5}

*該当のソースコードを動かすには 太字のコメント を解除してください。 .

!.section ".data"

!set1:.word 1 , 4 , 5 , 16

!set2:.word 1 , 4 , 7 , 23

!

!.section ".text"

!local variables

!n = -4

!

! index i in $l0

! max in $l1

!

!

.global main

!main :

save %sp, -96 ,%sp

!

set set1, %l2

!    st %l2,[%sp + 16 ]

!    mov 1 ,%o1

!    call mapinc

!   mov %l2,%o0

!test :

ret

!

restore

!

!N= 4 ! ( if N = 4 , it 's only works in {a,b,c,d} just 4 objects)

.global mapinc

mapinc :    save %sp, -96 ,%sp

mov 1 ,%l0

sll %l0,N,%l5 ! 2 ^N to l5 (this time 2 ^ 4 = 16 )

add %fp,%l5,%o3 ! address %fp +16

ld [%o3],%o0 ! right value of [%fp +16 ]

ba loop ! or not goto loop

clr %l0

indexup :   inc %l0 ! increase index ++

loop:       sll %l0, 2 ,%l2 ! address l2 = i* 4

add %o0,%l2,%o1 ! [%fp +16 +i* 4 ]

ld [%o1],%l1    ! load [%fp +16 +i* 4 ]

add %l1,%i1,%l1 ! add   %l1 = %l1 + %i1

st %l1,[%o1]    ! store %l1 to [%fp +16 +i* 4 ]

cmp %l0,N       ! compare %l0 < N

bl,a indexup    ! if true goto indexup

nop

ret

restore




取るに足らないソースコードがすべて終わりました...
今回の課題をしながら感じたのは、配列のアドレスにアクセスする際にビット処理を行うと、別途 mul を使用してアドレス計算をしなくてもよいということです。非常に便利です。
もちろん、ソースは最適化されていません。私は超初心者ですから..

だいたいソースを組むのに6時間の試行錯誤がかかりました。デバッグをしてメモリに何があるのか一つ一つ確認してみました。

あ、デバッグ時に使用するコマンドとしては..

- gcc -g main.c -o main     ::  main.c ファイルを global ラベルを参照可能にコンパイルし、main という名前の実行ファイルを出力する。

- gdb main   :: main をデバッグする。

- p $i0    ::  %i0  、 i0 レジスタの値を表示する。
- p set1   ::  静的変数 set1 の n 番目までの値を確認する
ex) -p set1    >> {1 , 4 , 5 }


私が理解した内容が多く間違っている可能性があります。正していただければ修正するようにします。
ありがとうございます。

AD