[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): 集合中每個元素加上 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 或 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 暫存器的值。
- p set1   ::  確認靜態變數 set1 到第 n 個的值。
ex) -p set1    >> {1 , 4 , 5 }


我所理解的內容可能有許多錯誤。若能協助指正,我會進行修正。
謝謝。

AD