You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Dec 21, 2022. It is now read-only.
I'd like inline assembly code to have the same syntax both in C and Onyx worlds.
The following structure is proposed.
@{ denotes an assembly statement.
Invoking it is unsafe.
There are three (possibly more) clauses in an assembly statement:
template containing assembly string;
in listing inputs;
out listing outputs.
Assembly string, register names and possible modifiers are optionally wrapped in backticks to reflect their low-level nature.
In practice, a compilation process is aware of the target machine assembly definitions.
Therefore, no explicit marking of the target in the code is required (e.g. no need to specify x86 anywhere).
If a template string, a register name, some kind of modifier or other semantic is erroneous, a compiler would panic.
As this is being an LLVM ASM, the link doesn't contain definitions for this specific case, but gives a general idea.
The example resides in the Fancy Onyx compiler built-in folder.
In a user library a concrete target-specific ASM would be used instead.
It can be done simply via macros, e.g. {% case nx.target.isa %}; {% when "x86" %}.
Maybe it's worth to standardize LLVM ASM rules as well.
In this example, r is a simple virtual register.
export struct Int<Signed: S ~ \Bool, Bitsize: Z ~ \UInt> : Real {
impl ~Real.add(another : self) : self throws Overflow {
final result = unsafe! uninitialized self
final overflow? = unsafe! uninitialized Bool
unsafe! @{
template \{{
# The following is a Ruby code.
# An emitting macro latest expression is printed to the source code as-is.
#
signed = nx["S"].value ? 's' : 'u'
lltype = "i" + nx["Z"].value
<<-LLIR
%res = call {#{ lltype }, i1} @llvm.#{ signed }add.\
with.overflow.#{ lltype }(#{ lltype } $0, #{ lltype } $1)
$2 = extractvalue {#{ lltype }, i1} %res, 1
LLIR
}}
in r(this), r(another)
out =r(overflow?)
}
if (overflow?) {
throw Overflow()
} else {
unsafe! @{
template
{{ "$0 = extractvalue {#{ lltype }, i1} %res, 0" }}
out =r(result)
}
return result
}
}
}
# Would evaluate to this:
reimpl Int<true, 32>~Real.add(another) {
final result = unsafe! uninitialized self
final overflow? = unsafe! uninitialized Bool
unsafe! @{
template
%res = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 $0, i32 $1)
$2 = extractvalue {i32, i1} %res, 1
in r(this), r(another)
out =r(overflowed?)
}
if (overflow?) {
throw Overflow()
} else {
unsafe! @{
template
$0 = extractvalue {i32, i1} %res, 0
out =r(result)
}
return result
}
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I'd like inline assembly code to have the same syntax both in C and Onyx worlds.
The following structure is proposed.
@{
denotes an assembly statement.Invoking it is unsafe.
There are three (possibly more) clauses in an assembly statement:
template
containing assembly string;in
listing inputs;out
listing outputs.Assembly string, register names and possible modifiers are optionally wrapped in backticks to reflect their low-level nature.
In practice, a compilation process is aware of the target machine assembly definitions.
Therefore, no explicit marking of the target in the code is required (e.g. no need to specify
x86
anywhere).If a template string, a register name, some kind of modifier or other semantic is erroneous, a compiler would panic.
I propose that the Standard defines semantics for specific targets; or at least links to such (see https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html for example).
The following example uses LLIR as assembly language.
See https://llvm.org/docs/LangRef.html#inline-assembler-expressions for LLVM ASM syntax rules.
As this is being an LLVM ASM, the link doesn't contain definitions for this specific case, but gives a general idea.
The example resides in the Fancy Onyx compiler built-in folder.
In a user library a concrete target-specific ASM would be used instead.
It can be done simply via macros, e.g.
{% case nx.target.isa %}; {% when "x86" %}
.Maybe it's worth to standardize LLVM ASM rules as well.
In this example,
r
is a simple virtual register.Beta Was this translation helpful? Give feedback.
All reactions