Где найти описание для @hi и @lo "инструкций" сборки OR1K

Я изучаю сборку OR1K для проекта, над которым я работаю. clang а также LLVM используются для обеспечения внешнего интерфейса и заднего конца для компилятора. Я нашел эту ссылку, и это почти все, что мне нужно, однако сборка, которую я смотрю, имеет @hi а также @lo символы в нем. У меня есть интуитивное понимание этих "инструкций", но было бы лучше получить официальное объяснение того, что они значат.

Ниже приведены C и соответствующий код сборки, который был сгенерирован для него. Сборочные линии, о которых я говорю, находятся практически внизу. Вот как они выглядят

l.sw    0(r1), r11
l.movhi r3, hi(.L.str@hi)
l.jal   printf
l.ori   r3, r3, lo(.L.str@lo)

Код C

#include <stdio.h>
#include <assert.h>

int sum(int a, int b) {
  return a + b;
}

int main(int argc, char** argv) {
  printf("Hello World! %d\n", sum(argc, 1));
  return 0;
}

Код сборки

    .text
    .file   "hello_world.ll"
    .globl  _Z3sumii
    .align  4
    .type   _Z3sumii,@function
_Z3sumii:                               # @_Z3sumii
    .cfi_startproc
# BB#0:                                 # %entry
    l.sw    -4(r1), r2
.Ltmp0:
    .cfi_offset 2, -4
    l.addi  r2, r1, 0
.Ltmp1:
    .cfi_def_cfa_register 2
    l.addi  r1, r1, -12
    l.sw    -8(r2), r3
    l.sw    -12(r2), r4
    l.lwz   r3, -8(r2)
    l.add   r11, r3, r4
    l.addi  r1, r2, 0
    l.jr    r9
    l.lwz   r2, -4(r1)
.Ltmp2:
    .size   _Z3sumii, .Ltmp2-_Z3sumii
    .cfi_endproc

    .globl  main
    .align  4
    .type   main,@function
main:                                   # @main
    .cfi_startproc
# BB#0:                                 # %entry
    l.sw    -4(r1), r9
.Ltmp3:
    .cfi_offset 9, -4
    l.sw    -8(r1), r2
.Ltmp4:
    .cfi_offset 2, -8
    l.addi  r2, r1, 0
.Ltmp5:
    .cfi_def_cfa_register 2
    l.addi  r13, r1, -32
    l.srli  r13, r13, 3
    l.slli  r1, r13, 3
    l.movhi r5, 0
    l.sw    20(r1), r5
    l.sw    16(r1), r3
    l.sw    8(r1), r4
    l.lwz   r3, 16(r1)
    l.jal   _Z3sumii
    l.addi  r4, r0, 1
    l.sw    0(r1), r11
    l.movhi r3, hi(.L.str@hi)
    l.jal   printf
    l.ori   r3, r3, lo(.L.str@lo)
    l.movhi r11, 0
    l.addi  r1, r2, 0
    l.lwz   r9, -4(r1)
    l.jr    r9
    l.lwz   r2, -8(r1)
.Ltmp6:
    .size   main, .Ltmp6-main
    .cfi_endproc

    .type   .L.str,@object          # @.str
    .section    .rodata.str1.1,"aMS",@progbits,1
.L.str:
    .asciz  "Hello World! %d\n"
    .size   .L.str, 17

Любая помощь приветствуется.

1 ответ

OpenRISC, как и многие языки ассемблера, может использовать только 16-битные непосредственные значения. Таким образом, чтобы выполнить загрузку, он сначала загружает старшие 16 бит, а затем выполняет операцию или с младшими 16 битами. В псевдо-С:

int32_t addr = &str;
register r3;
r3 = addr & 0xFFFF0000; /* load hi bits, note this is a 16 bit value */
r3 |= addr &0xFFFF; /* load the lo bits of addr, note again only a 16 bit value */

Тогда что же происходит с вызовом printf по обе стороны от нагрузки r3? Ну, у OpenRISC есть слот задержки ветвления. Таким образом, вызов printf происходит после инструкции or.

Другие вопросы по тегам