2

Github Add support for const operands and options to global_asm! by Amanieu · Pu...

 3 years ago
source link: https://github.com/rust-lang/rust/pull/84107
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Copy link

Contributor

nagisa left a comment

Welp, that took way longer than I expected it would.

See comments inline. No major issues other than the one with the collector.

r=me once comments are acknowledged/resolved.

ty::IntTy::I128 => (value as i128).to_string(),

ty::IntTy::Isize => unreachable!(),

},

ty::Float(ty::FloatTy::F32) => f32::from_bits(value as u32).to_string(),

nagisa on Apr 24

Contributor

Is it intended that this uses a decimal representation of the float as opposed to writing out a hex value representing the encoding of the float? I don't recall seeing any other way to represent floats in assembly than their hex encoding.

I'm worried mostly that encoding a float here could lead to double-rounding resembling issues – we had some of those in the past where the Rust's formatting algorithm used to produce very slightly different results than those produced by C, but both still "correct". Encoding the bits representation of the float would make me much more comfortable with this.

nagisa on Apr 24

Contributor

That said it seems preexisting… so shrug

Amanieu on Apr 26

Author

Contributor

I'm actually considering getting rid of float constants and only supporting integers. It would work better with typeck too.

};

let value = scalar.assert_bits(ty_and_layout.size);

match ty_and_layout.ty.kind() {

ty::Uint(_) => value.to_string(),

nagisa on Apr 24

Contributor

Hm, so I have questions about this. Many architectures have separate instructions that sign-extend or zero-extend the constant operands from, say, 12-bits to the register bit width. Do i recall correctly that otherwise the assembler implementations don't particularly care about whether the constant is represented as a wrapped signed integer or a unsigned integer, as far as it is in range of the maximum bit width for the instruction?

This is probably the correct implementation regardless, but it seems like it could result in some weird action at a distance behaviour.

Amanieu on Apr 26

Author

Contributor

Our job in rustc is to emit the given constant as a string. The actual interpretation of that string is up to the assembler and is not our problem.

The most sensible way of handling this is to format based on the original type of the value, just like format! does.

nagisa on May 1

Contributor

The problem is exactly in how different pieces of software interpret the same decimal float string. There's very often a difference between different interpretations. Outputting the float as a hexadecimal bit representation avoids this issue entirely and the only party in control of what float ends up being encoded in the binary is Rust. Which sounds like an improvement to me.

global_asm!("{}", const 0);

global_asm!("{}", const 0i32);

global_asm!("{}", const 0f32);

global_asm!("{}", const 0 as *mut u8);

nagisa on Apr 24

Contributor

Allowing pointers may be useful for e.g. embedded use-cases where people might want to refer to e.g. peripherals.

Amanieu on Apr 26

Author

Contributor

There is a separate sym operand type for this which inserts a symbol name. It is not supported in global_asm! yet but will be in the future.

nagisa on May 1

Contributor

Ah, I meant something different. Like

const GPIOA: *const u32 = 0x8000_4200;

and then users trying to use that pointer as-is. Symbol isn't quite usable here because placing the symbol in the right place would require linker shenanigans people don't generally love all that much.

src/test/ui/asm/bad-arch.stderr

Outdated

Show resolved


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK