How does Rust's 128-bit integer `i128` work on a 64-bit system?

前端 未结 4 757
北荒
北荒 2021-01-30 19:16

Rust has 128-bit integers, these are denoted with the data type i128 (and u128 for unsigned ints):

let a: i128 = 1701411834604692317316         


        
4条回答
  •  一整个雨季
    2021-01-30 19:34

    All Rust's integer types are compiled to LLVM integers. The LLVM abstract machine allows integers of any bit width from 1 to 2^23 - 1.* LLVM instructions typically work on integers of any size.

    Obviously, there aren't many 8388607-bit architectures out there, so when the code is compiled to native machine code, LLVM has to decide how to implement it. The semantics of an abstract instruction like add are defined by LLVM itself. Typically, abstract instructions that have a single-instruction equivalent in native code will be compiled to that native instruction, while those that don't will be emulated, possibly with multiple native instructions. mcarton's answer demonstrates how LLVM compiles both native and emulated instructions.

    (This doesn't only apply to integers that are larger than the native machine can support, but also to those that are smaller. For example, modern architectures might not support native 8-bit arithmetic, so an add instruction on two i8s may be emulated with a wider instruction, the extra bits discarded.)

    Does the compiler somehow use 2 registers for one i128 value? Or are they using some kind of big integer struct to represent them?

    At the level of LLVM IR, the answer is neither: i128 fits in a single register, just like every other single-valued type. On the other hand, once translated to machine code, there isn't really a difference between the two, because structs may be decomposed into registers just like integers. When doing arithmetic, though, it's a pretty safe bet that LLVM will just load the whole thing into two registers.


    * However, not all LLVM backends are created equal. This answer relates to x86-64. I understand that backend support for sizes larger than 128 and non-powers of two is spotty (which may partly explain why Rust only exposes 8-, 16-, 32-, 64-, and 128-bit integers). According to est31 on Reddit, rustc implements 128 bit integers in software when targeting a backend that doesn't support them natively.

提交回复
热议问题