xo-expression: + several arithmetic intrinsics

This commit is contained in:
Roland Conybeare 2024-06-24 15:09:27 -04:00
commit d94e16eecd

View file

@ -19,9 +19,18 @@ namespace xo {
* can use the associated llvm instrinsic instead of generating a function call
* @c Primitive::value
*
* @note llvm will still need to use @c Primitive::value, for example
* when handling an @c xo::ast::Apply instance where the function position
* is a computed function.
* @note llvm will still sometimes need to use
* @c Primitive::value (and generate a function call sequence),
* for example when handling an @c xo::ast::Apply instance
* where the function position is a computed function.
* @endnote
*
* @note
* LLVM requires separate intrinsics for {ints, floats}.
* It does not need separate intrinsics for different sizes.
* For example IRBuilder::CreateAdd works for
* {8-bit, 16-bit, 32-bit, 64-bit, 128-bit} x {signed, unsigned} integers
* Integer division is an exception; need to choose between i_sdiv and i_udiv
* @endnote
*
* @note
@ -30,21 +39,38 @@ namespace xo {
* @endnote
**/
enum class llvmintrinsic {
// see /nix/store/x5yz...llvm-18.1.5-dev/include/llvm/IR/IRBuilder.h
/** sentinel value **/
invalid = -1,
/** -> IRBuilder::CreateNeg (negate 1 integer) **/
i_neg,
/** -> IRBuilder::CreateAdd (add 2 integers, overflow silently) **/
i_add,
/** -> IRBuilder::CreateSub (subtract 2 integers, overflow silently) **/
i_sub,
/** -> IRBuilder::CreateMul (multiply 2 integers, overflow silently) **/
i_mul,
/** -> IRBuilder::CreateSdiv (divide 2 signed integers) **/
i_sdiv,
/** -> IRBuilder::CreateUdiv (divide 2 unsigned integers) **/
i_udiv,
/** -> IRBuilder::CreateFadd (add 2 floating-point numbers) **/
fp_add,
/** -> IRBuilder::CreateFmul (multiply 2 floating-point numbers) **/
fp_mul,
/** -> IRBuilder::CreateFdiv (divide 2 floating-point numbers) **/
fp_div,
/**
* want to do whatever llvm IR @c llvm.sqrt.f64 and friends do.
* Not sure if that's an always-available function of something else
@ -72,10 +98,15 @@ namespace xo {
{
switch(x) {
case llvmintrinsic::invalid: return "?llvminstrinsic";
case llvmintrinsic::i_neg: return "i_neg";
case llvmintrinsic::i_add: return "i_add";
case llvmintrinsic::i_sub: return "i_sub";
case llvmintrinsic::i_mul: return "i_mul";
case llvmintrinsic::i_sdiv: return "i_sdiv";
case llvmintrinsic::i_udiv: return "i_udiv";
case llvmintrinsic::fp_add: return "fp_add";
case llvmintrinsic::fp_mul: return "fp_mul";
case llvmintrinsic::fp_div: return "fp_div";
case llvmintrinsic::fp_sqrt: return "fp_sqrt";
case llvmintrinsic::fp_pow: return "fp_pow";
case llvmintrinsic::fp_sin: return "fp_sin";