Skip to main content

Module quad

Module quad 

Source
Expand description

The float that is wider than any instruction, as the calls that do the work.

_Float128 is the one arithmetic type a C program writes that no machine computes with. Sixteen bytes fit in a vector register, so moving one, passing one and returning one are instructions this back end has, and spec/10-backend.md section 10.8’s rule set is written at this width for exactly those three. Everything else is a call: no processor anyone compiles for has an instruction that adds two binary128 values, which is why spec/12-abi-and-runtime.md section 12.8 puts the whole format in the runtime rather than in the part of the runtime that exists for targets with no floating point unit. This pass is what turns the operation the program wrote into the call the routine is.

After it there is no arithmetic, no comparison and no conversion at this format left in the function, which is what lets the selector go on being a table over widths the machine has. What is left at the width is the three things a rule is written for, and a call is one of them in the sense that matters: the value travels in the register the convention names.

§Why a pass and not a rule

The same reason crate::wide is a pass. A rule rewrites a term into instructions of the machine, and there is no instruction here to rewrite into, so there is nothing for a rule to produce. A call is not a rewrite of a term either, because what it needs first is the convention’s answer about where each operand goes, which is crate::abi’s and not a rule’s.

§The names are libgcc’s, and the spelling is a target fact

__addtf3 and the rest, which is what runtime/builtins/quad.c defines and what libgcc defines beside it, so a call this pass writes links against either. The tf in the name means binary128 on every target this compiler has a back end for, and on ppc64 it does not: there long double is a pair of doubles, __addtf3 is the arithmetic on that pair, and binary128 is spelled kf. So the table below is right for the back ends that exist and is the first thing to look at when a ppc64 one does, which is tamnd/rucc#618’s row rather than this pass’s business today.

§What is left alone

An operation at this format whose routine is not in the archive is left exactly as it was and refused below by name, the same way crate::wide leaves a conversion at eighty bits alone. That is a conversion against a _Float16 or an eighty bit float, and a select of two quads, which is a move the rule set has no conditional form of. A refusal naming the instruction is the outcome every one of those had before this pass existed and it is still the right one: the alternative is a call to a routine no archive defines, which is a link that fails further from the cause.

A conversion against a __int128 is not in that list and is not this pass’s work either. crate::wide runs above here and turns one into a call to __floattitf, __floatuntitf, __fixtfti or __fixunstfti, with the integer as the pair of words the convention passes it in, so by the time this pass looks there is nothing at that width left to refuse.

Functions§

calls
Rewrites every operation at this format into the call that performs it.