ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Operands of the Computer Hardware | RISC-V
    Computer Science/Computer Architecture and Organization 2021. 4. 22. 23:39

    high-level 프로그램 언어와는 다르게, 하드웨어쪽에서 실행되는 operands는 다르게 처리가 되는데, 이것은 하드웨어에서 registers 라고 불리는 장소에서 이뤄져야한다. RISC-C의 아키텍쳐는 64bits를 보통 사용한다. 이는 doubleword라고도 부른다. (32bits도 많이 쓰이는데, 이는 word라고 한다). 프로그래밍 언어와 registers의 차이는, 제한적이라는것인데, 보통 32개의 register를 쓴다. 그렇기때문에, RISC-V 연산이 될 때, 32개의 64-bit 크기의 레지스터들중 하나에서 처리되어야 한다. 아래 문제를 보자.

    Compiling a C Assignment Using Registers

    Example

    It is the compiler’s job to associate program variables with registers. Take, for instance, the assignment statement from our earlier example:

    f = (g + h) −(i + j);

    The variables f, g, h, i, and j are assigned to the registers x19, x20, x21, x22, and x23, respectively. What is the compiled RISC-V code?

    컴파일러가 이 전 포스트에서 연습했던 수식을 계산하는데, registers에 저장되어있는 값들(x19, x20, x21, x22, and x23)을 이용해서 수식을 완성하라는 문제이다. 아래와같이 해볼 수 있다. 

    add x5, x20, x21 // x20에 저장된 g, x21에 저장된 h를 더한다.
    add x6, x22, x23 // x22에 저장된 i, x23에 저장된 j를 더한다.
    sub x19, x5, x6 // 임시 저장해둔 값을 이용해 뺄셈 후 최종값을 x19에 저장한다.

     

    위에서 언급했던것처럼, 연산은 registers에서만 일어난다. 그러므로 RISC-V는 반드시 memory에서 registers로 데이터를 운반해야하고, 이것을 data transfer instructions 라고 한다. 메모리에 있는 word나 doubleword를 엑세스 하려면, instruction은 메모리 주소를 주어야한다. 메모리는 아주 큰 1차원의 array이다. 이는 이전 포스트에서 커버했던 MIPS와도 동일한 방식이다. 아래 문제를 풀어보자.

    Compiling an Assignment When an Operand Is in Memory

    Example

    Let’s assume that A is an array of 100 doublewords and that the compiler has associated the variables g and h with the registers x20 and x21 as before. Let’s also assume that the starting address, or base address, of the array is in x22. Compile this C assignment statement:

    g = h + A[8];

    A라는 Array가 있는고, 그안에는 100개의 doublewords (64bits)가 있는데, register x20, x21에 g와 h가 있고, Array A의 base address는 x22에 저장되어있을 때, 수식을 RISC-V로 변환하라는 문제이다. 

     

    먼저, A[8]에 있는 값을 x9 레지스터에 옮겨서 (load data, ld) 값을 더해 최종 레지스터에 저장해주면 된다.

    ld x9, 8(x22) // temporory register x9에 A[8]값을 저장한다
    add x20, x21, x9 // 저장된 값과 x21에 있는 h값을 더해 x20에 저장한다.

     

    그런데, MIPS와 마찬가지로, A[8]의 값은 8(x22)에 있지 않다. 실제 RISC-V 메모리 주소는 8byte단위로 나누어진다. 그래서 정확하게 표현하면 8 * 8, 즉 64(x22)이어야 A[8]값을 찾을 수 있고, 8(x22)는, A[1]의 값이 저장되어있다. 즉, 아래와같이 표현해야 정확하다.

    ld x9, 64(x22) // temporory register x9에 A[8]값을 저장한다
    add x20, x21, x9 // 저장된 값과 x21에 있는 h값을 더해 x20에 저장한다.

     

    그렇다면 아래 문제는 어떨까?

    Compiling Using Load and Store

    Example

    Assume variable h is associated with register x21 and the base address of the array A is in x22. What is the RISC-V assembly code for the C assignment statement below?

    A[12] = h + A[8];

    단순 레지스터에 저장을 해서 끝내는 문제가 아닌, 메모리에 그 값을 돌려줘야하는 문제이다. 이떄, sd (store data)를 이용할 수 있다. 

     

    ld x9, 64(x22) // A[8]의 값을 temp register인 x9에 저장
    add x9, x21, x9 // h와 temp register인 x9에 저장되어있는 A[8] 값을 더해서, 다시 x9 register에 저장
    sd x9, 96(x22) // A[12]의 메모리 (base인 x22에서 96(8 * 12)만큼 가야함)에 register x9에 저장된 계산된값을 복사

     

     

    Reference

    David A. Patterson and John L. Hennessy. 2013. Computer Organization and Design, Fifth Edition: The Hardware/Software Interface (5th. ed.). Morgan Kaufmann Publishers Inc., San Francisco, CA, USA.

    댓글

Designed by Tistory.