LLVM任意精度整数

Gde*_*elP 7 types llvm llvm-ir

LLVM 语言参考说明了这一点

整数类型是一种非常简单的类型,它只是为所需的整数类型指定任意位宽.可以指定从1位到2 23 -1(大约8百万)的任何位宽.

这是否意味着我可以免费使用任意固定长度的整数?也就是说,如果我声明一个i100,我会有一个100位宽的变量吗?

Ste*_*ehl 9

我不完全确定你的意思是"免费",但是LLVM会让你做到并在某些平台上编译它.但是,与在CPU寄存器的倍数上调整大小的类型相比,它将付出代价.

如果你创建i100它,它在堆栈上分配一个100位的块.如果对它进行操作,则将限制为CPU为指令集提供的任何内容.如果要添加两个64位整数,IR将如下所示:

define i64 @add(i64 %a, i64 %b) {
  %1 = add i64 %a, %b
  ret i64 %1
}
Run Code Online (Sandbox Code Playgroud)

然后我们得到生成的程序集,通常是一条指令:

add:                                    # @add
    .cfi_startproc
# BB#0:
    addq    %rsi, %rdi
    movq    %rdi, %rax
    ret
Run Code Online (Sandbox Code Playgroud)

但是,例如,如果你工作,我们想i1024在以下IR中添加两个整数:

define i1024 @add(i1024 %a, i1024 %b) {
  %1 = add i1024 %a, %b
  ret i1024 %1
}
Run Code Online (Sandbox Code Playgroud)

然后为x86-64系统生成的程序集就是这种非常有效的指令集合,其中很多只是mov内存周围的内存.

add:                                    # @add
    .cfi_startproc
# BB#0:
    pushq   %r15
.Ltmp5:
    .cfi_def_cfa_offset 16
    pushq   %r14
.Ltmp6:
    .cfi_def_cfa_offset 24
    pushq   %r12
.Ltmp7:
    .cfi_def_cfa_offset 32
    pushq   %rbx
.Ltmp8:
    .cfi_def_cfa_offset 40
.Ltmp9:
    .cfi_offset %rbx, -40
.Ltmp10:
    .cfi_offset %r12, -32
.Ltmp11:
    .cfi_offset %r14, -24
.Ltmp12:
    .cfi_offset %r15, -16
    movq    40(%rsp), %r10
    addq    128(%rsp), %rsi
    adcq    136(%rsp), %rdx
    adcq    144(%rsp), %rcx
    adcq    152(%rsp), %r8
    adcq    160(%rsp), %r9
    movq    96(%rsp), %r14
    movq    104(%rsp), %r11
    movq    80(%rsp), %r12
    movq    88(%rsp), %r15
    adcq    168(%rsp), %r10
    movq    64(%rsp), %rax
    movq    72(%rsp), %rbx
    movq    %rsi, (%rdi)
    movq    %rdx, 8(%rdi)
    movq    48(%rsp), %rsi
    movq    56(%rsp), %rdx
    movq    %rcx, 16(%rdi)
    movq    %r8, 24(%rdi)
    movq    %r9, 32(%rdi)
    movq    112(%rsp), %rcx
    movq    120(%rsp), %r8
    adcq    176(%rsp), %rsi
    adcq    184(%rsp), %rdx
    adcq    192(%rsp), %rax
    adcq    200(%rsp), %rbx
    adcq    208(%rsp), %r12
    adcq    216(%rsp), %r15
    adcq    224(%rsp), %r14
    movq    %r10, 40(%rdi)
    movq    %rsi, 48(%rdi)
    movq    %rdx, 56(%rdi)
    movq    %rax, 64(%rdi)
    movq    %rbx, 72(%rdi)
    movq    %r12, 80(%rdi)
    movq    %r15, 88(%rdi)
    movq    %r14, 96(%rdi)
    adcq    232(%rsp), %r11
    movq    %r11, 104(%rdi)
    adcq    240(%rsp), %rcx
    movq    %rcx, 112(%rdi)
    adcq    248(%rsp), %r8
    movq    %r8, 120(%rdi)
    popq    %rbx
    popq    %r12
    popq    %r14
    popq    %r15
    ret
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用 LLVM 静态编译器实用程序“llc”来测试 LLVM 代码并查看其编译结果,如本答案中所做的那样。只需将 LLVM 代码放入扩展名为“.ll”的文件中,并将文件名传递给“llc”,这将生成一个“.s”文件。 (2认同)