Module:       llvm-internals
Copyright:    Original Code is Copyright 2010 Gwydion Dylan Maintainers
              All rights reserved.
License:      See License.txt in this distribution for details.
Warranty:     Distributed WITHOUT WARRANTY OF ANY KIND

/// Intrinsics support

define constant $llvm-intrinsic-default-function-attributes
  = $llvm-attribute-nounwind;
define constant $llvm-intrinsic-default-attribute-list
  = make(<llvm-attribute-list>,
         function-attributes: $llvm-intrinsic-default-function-attributes);

define constant $llvm-intrinsic-readonly-function-attributes
  = llvm-attribute-merge($llvm-attribute-nounwind, $llvm-attribute-readonly);
define constant $llvm-intrinsic-readonly-attribute-list
  = make(<llvm-attribute-list>,
         function-attributes: $llvm-intrinsic-readonly-function-attributes);

define constant $llvm-intrinsic-readnone-function-attributes
  = llvm-attribute-merge($llvm-attribute-nounwind, $llvm-attribute-readnone);
define constant $llvm-intrinsic-readnone-attribute-list
  = make(<llvm-attribute-list>,
         function-attributes: $llvm-intrinsic-readnone-function-attributes);

define method intrinsic-type-name (type :: <llvm-integer-type>)
  format-to-string("i%d", type.llvm-integer-type-width)
end method;

define method intrinsic-type-name (type :: <llvm-pointer-type>)
  format-to-string("p%d%s", type.llvm-pointer-type-address-space,
                   intrinsic-type-name(type.llvm-pointer-type-pointee))
end method;

define method intrinsic-type-name (type :: <llvm-vector-type>)
  format-to-string("v%d%s", type.llvm-vector-type-size,
                   intrinsic-type-name(type.llvm-vector-type-element-type))
end method;

define method intrinsic-type-name (type :: <llvm-primitive-type>)
  select (type.llvm-primitive-type-kind)
    #"FLOAT" => "f32";
    #"DOUBLE" => "f64";
    #"X86_FP80" => "f80";
    #"FP128" => "f128";
    #"PPC_FP128" => "ppcf128";
    #"METADATA" => "Metadata";
  end select
end method;

define inline method intrinsic-type-name
    (type :: <llvm-placeholder-type>)
  intrinsic-type-name(type.llvm-placeholder-type-forward)
end method;

/*
define method truncate-vector-type (type :: <llvm-vector-type>)
  make(<llvm-vector-type>,
       size: truncate/(type.llvm-vector-type-size, 2),
       element-type: type.llvm-vector-type-element-type)
end method;

define inline method truncate-vector-type
    (type :: <llvm-placeholder-type>)
  truncate-vector-type(type.llvm-placeholder-type-forward)
end method;

define method extend-vector-type (type :: <llvm-vector-type>)
  make(<llvm-vector-type>,
       size: type.llvm-vector-type-size * 2,
       element-type: type.llvm-vector-type-element-type)
end method;

define inline method extend-vector-type
    (type :: <llvm-placeholder-type>)
  extend-vector-type(type.llvm-placeholder-type-forward)
end method;
*/

define constant $llvm-intrinsic-makers = make(<string-table>);


/// Generated intrinsics code

// Do not edit the code below the cut line; it is generated by running
// the llvm-tablegen program (see sources/app/llvm-tablegen) on the
// Intrinsics.td file from the current LLVM release. For example, if
// LLVM is installed in /usr/local, run
//
// llvm-tablegen -I /usr/local/include -gen-intrinsic /usr/local/include/llvm/IR/Intrinsics.td
//
// -------------------------------- cut --------------------------------
begin
  $llvm-intrinsic-makers["llvm.adjust.trampoline"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i8*-type,
                  parameter-types: vector($llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.adjust.trampoline",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-readonly-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.annotation"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.annotation.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0, $llvm-i8*-type, $llvm-i8*-type, $llvm-i32-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-default-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.bswap"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.bswap.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.ceil"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.ceil.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.convert.from.fp16"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-float-type,
                  parameter-types: vector($llvm-i16-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.convert.from.fp16",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-readnone-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.convert.to.fp16"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i16-type,
                  parameter-types: vector($llvm-float-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.convert.to.fp16",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-readnone-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.convertff"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         let type1 = llvm-value-type(arguments[0]);
         let name = format-to-string("llvm.convertff.%s.%s", intrinsic-type-name(type0), intrinsic-type-name(type1));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type1, $llvm-i32-type, $llvm-i32-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-default-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.convertfsi"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         let type1 = llvm-value-type(arguments[0]);
         let name = format-to-string("llvm.convertfsi.%s.%s", intrinsic-type-name(type0), intrinsic-type-name(type1));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type1, $llvm-i32-type, $llvm-i32-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-default-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.convertfui"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         let type1 = llvm-value-type(arguments[0]);
         let name = format-to-string("llvm.convertfui.%s.%s", intrinsic-type-name(type0), intrinsic-type-name(type1));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type1, $llvm-i32-type, $llvm-i32-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-default-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.convertsif"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         let type1 = llvm-value-type(arguments[0]);
         let name = format-to-string("llvm.convertsif.%s.%s", intrinsic-type-name(type0), intrinsic-type-name(type1));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type1, $llvm-i32-type, $llvm-i32-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-default-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.convertss"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         let type1 = llvm-value-type(arguments[0]);
         let name = format-to-string("llvm.convertss.%s.%s", intrinsic-type-name(type0), intrinsic-type-name(type1));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type1, $llvm-i32-type, $llvm-i32-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-default-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.convertsu"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         let type1 = llvm-value-type(arguments[0]);
         let name = format-to-string("llvm.convertsu.%s.%s", intrinsic-type-name(type0), intrinsic-type-name(type1));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type1, $llvm-i32-type, $llvm-i32-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-default-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.convertuif"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         let type1 = llvm-value-type(arguments[0]);
         let name = format-to-string("llvm.convertuif.%s.%s", intrinsic-type-name(type0), intrinsic-type-name(type1));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type1, $llvm-i32-type, $llvm-i32-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-default-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.convertus"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         let type1 = llvm-value-type(arguments[0]);
         let name = format-to-string("llvm.convertus.%s.%s", intrinsic-type-name(type0), intrinsic-type-name(type1));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type1, $llvm-i32-type, $llvm-i32-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-default-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.convertuu"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         let type1 = llvm-value-type(arguments[0]);
         let name = format-to-string("llvm.convertuu.%s.%s", intrinsic-type-name(type0), intrinsic-type-name(type1));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type1, $llvm-i32-type, $llvm-i32-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-default-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.cos"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.cos.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.ctlz"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.ctlz.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0, $llvm-i1-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.ctpop"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.ctpop.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.cttz"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.cttz.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0, $llvm-i1-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.dbg.declare"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-metadata-type, $llvm-metadata-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.dbg.declare",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-readnone-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.dbg.value"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-metadata-type, $llvm-i64-type, $llvm-metadata-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.dbg.value",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-readnone-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.debugtrap"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector(),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.debugtrap",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.donothing"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector(),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.donothing",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-readnone-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.eh.dwarf.cfa"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i8*-type,
                  parameter-types: vector($llvm-i32-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.eh.dwarf.cfa",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.eh.return.i32"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i32-type, $llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.eh.return.i32",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.eh.return.i64"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i64-type, $llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.eh.return.i64",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.eh.sjlj.callsite"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i32-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.eh.sjlj.callsite",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-readnone-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.eh.sjlj.functioncontext"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.eh.sjlj.functioncontext",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.eh.sjlj.longjmp"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.eh.sjlj.longjmp",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.eh.sjlj.lsda"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i8*-type,
                  parameter-types: vector(),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.eh.sjlj.lsda",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-readnone-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.eh.sjlj.setjmp"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i32-type,
                  parameter-types: vector($llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.eh.sjlj.setjmp",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.eh.typeid.for"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i32-type,
                  parameter-types: vector($llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.eh.typeid.for",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-readnone-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.eh.unwind.init"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector(),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.eh.unwind.init",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.exp"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.exp.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.exp2"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.exp2.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.expect"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         llvm-constrain-type(type0, llvm-value-type(arguments[1]));
         let name = format-to-string("llvm.expect.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0, type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.fabs"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.fabs.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.floor"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.floor.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.flt.rounds"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i32-type,
                  parameter-types: vector(),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.flt.rounds",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.fma"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         llvm-constrain-type(type0, llvm-value-type(arguments[1]));
         llvm-constrain-type(type0, llvm-value-type(arguments[2]));
         let name = format-to-string("llvm.fma.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0, type0, type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.fmuladd"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         llvm-constrain-type(type0, llvm-value-type(arguments[1]));
         llvm-constrain-type(type0, llvm-value-type(arguments[2]));
         let name = format-to-string("llvm.fmuladd.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0, type0, type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.frameaddress"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i8*-type,
                  parameter-types: vector($llvm-i32-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.frameaddress",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-readnone-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.gcread"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i8*-type,
                  parameter-types: vector($llvm-i8*-type, make(<llvm-pointer-type>, pointee: $llvm-i8*-type)),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.gcread",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-readonly-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.gcroot"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector(make(<llvm-pointer-type>, pointee: $llvm-i8*-type), $llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.gcroot",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.gcwrite"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type, $llvm-i8*-type, make(<llvm-pointer-type>, pointee: $llvm-i8*-type)),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.gcwrite",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: make(<llvm-attribute-list>, function-attributes: $llvm-intrinsic-default-function-attributes, parameter-attributes: vector($llvm-attribute-none, $llvm-attribute-nocapture, $llvm-attribute-nocapture)),
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.init.trampoline"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type, $llvm-i8*-type, $llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.init.trampoline",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: make(<llvm-attribute-list>, function-attributes: $llvm-intrinsic-default-function-attributes, parameter-attributes: vector($llvm-attribute-nocapture, $llvm-attribute-none, $llvm-attribute-none)),
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.invariant.end"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector(make(<llvm-pointer-type>, pointee: make(<llvm-struct-type>, elements: vector())), $llvm-i64-type, $llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.invariant.end",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: make(<llvm-attribute-list>, function-attributes: $llvm-intrinsic-default-function-attributes, parameter-attributes: vector($llvm-attribute-none, $llvm-attribute-none, $llvm-attribute-nocapture)),
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.invariant.start"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: make(<llvm-pointer-type>, pointee: make(<llvm-struct-type>, elements: vector())),
                  parameter-types: vector($llvm-i64-type, $llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.invariant.start",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: make(<llvm-attribute-list>, function-attributes: $llvm-intrinsic-default-function-attributes, parameter-attributes: vector($llvm-attribute-none, $llvm-attribute-nocapture)),
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.lifetime.end"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i64-type, $llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.lifetime.end",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: make(<llvm-attribute-list>, function-attributes: $llvm-intrinsic-default-function-attributes, parameter-attributes: vector($llvm-attribute-none, $llvm-attribute-nocapture)),
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.lifetime.start"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i64-type, $llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.lifetime.start",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: make(<llvm-attribute-list>, function-attributes: $llvm-intrinsic-default-function-attributes, parameter-attributes: vector($llvm-attribute-none, $llvm-attribute-nocapture)),
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.log"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.log.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.log10"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.log10.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.log2"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.log2.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.longjmp"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type, $llvm-i32-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.longjmp",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.memcpy"]
    := method (arguments)
         let type0 = llvm-value-type(arguments[0]);
         let type1 = llvm-value-type(arguments[1]);
         let type2 = llvm-value-type(arguments[2]);
         let name = format-to-string("llvm.memcpy.%s.%s.%s", intrinsic-type-name(type0), intrinsic-type-name(type1), intrinsic-type-name(type2));

         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector(type0, type1, type2, $llvm-i32-type, $llvm-i1-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: make(<llvm-attribute-list>, function-attributes: $llvm-intrinsic-default-function-attributes, parameter-attributes: vector($llvm-attribute-nocapture, $llvm-attribute-nocapture, $llvm-attribute-none, $llvm-attribute-none, $llvm-attribute-none)),
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.memmove"]
    := method (arguments)
         let type0 = llvm-value-type(arguments[0]);
         let type1 = llvm-value-type(arguments[1]);
         let type2 = llvm-value-type(arguments[2]);
         let name = format-to-string("llvm.memmove.%s.%s.%s", intrinsic-type-name(type0), intrinsic-type-name(type1), intrinsic-type-name(type2));

         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector(type0, type1, type2, $llvm-i32-type, $llvm-i1-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: make(<llvm-attribute-list>, function-attributes: $llvm-intrinsic-default-function-attributes, parameter-attributes: vector($llvm-attribute-nocapture, $llvm-attribute-nocapture, $llvm-attribute-none, $llvm-attribute-none, $llvm-attribute-none)),
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.memset"]
    := method (arguments)
         let type0 = llvm-value-type(arguments[0]);
         let type1 = llvm-value-type(arguments[2]);
         let name = format-to-string("llvm.memset.%s.%s", intrinsic-type-name(type0), intrinsic-type-name(type1));

         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector(type0, $llvm-i8-type, type1, $llvm-i32-type, $llvm-i1-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: make(<llvm-attribute-list>, function-attributes: $llvm-intrinsic-default-function-attributes, parameter-attributes: vector($llvm-attribute-nocapture, $llvm-attribute-none, $llvm-attribute-none, $llvm-attribute-none, $llvm-attribute-none)),
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.nearbyint"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.nearbyint.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.objectsize"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         let name = format-to-string("llvm.objectsize.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector($llvm-i8*-type, $llvm-i1-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.pcmarker"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i32-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.pcmarker",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.pow"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         llvm-constrain-type(type0, llvm-value-type(arguments[1]));
         let name = format-to-string("llvm.pow.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0, type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.powi"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.powi.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0, $llvm-i32-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.prefetch"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type, $llvm-i32-type, $llvm-i32-type, $llvm-i32-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.prefetch",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: make(<llvm-attribute-list>, function-attributes: $llvm-intrinsic-default-function-attributes, parameter-attributes: vector($llvm-attribute-nocapture, $llvm-attribute-none, $llvm-attribute-none, $llvm-attribute-none)),
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.ptr.annotation"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.ptr.annotation.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0, $llvm-i8*-type, $llvm-i8*-type, $llvm-i32-type),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-default-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.readcyclecounter"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i64-type,
                  parameter-types: vector(),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.readcyclecounter",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.returnaddress"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i8*-type,
                  parameter-types: vector($llvm-i32-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.returnaddress",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-readnone-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.rint"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.rint.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.round"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.round.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.sadd.with.overflow"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         llvm-constrain-type(type0, llvm-value-type(arguments[1]));
         let name = format-to-string("llvm.sadd.with.overflow.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: make(<llvm-struct-type>, elements: vector(type0, $llvm-i1-type)),
                  parameter-types: vector(type0, type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.setjmp"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i32-type,
                  parameter-types: vector($llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.setjmp",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.siglongjmp"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type, $llvm-i32-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.siglongjmp",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.sigsetjmp"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i32-type,
                  parameter-types: vector($llvm-i8*-type, $llvm-i32-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.sigsetjmp",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.sin"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.sin.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.smul.with.overflow"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         llvm-constrain-type(type0, llvm-value-type(arguments[1]));
         let name = format-to-string("llvm.smul.with.overflow.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: make(<llvm-struct-type>, elements: vector(type0, $llvm-i1-type)),
                  parameter-types: vector(type0, type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.sqrt"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.sqrt.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.ssub.with.overflow"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         llvm-constrain-type(type0, llvm-value-type(arguments[1]));
         let name = format-to-string("llvm.ssub.with.overflow.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: make(<llvm-struct-type>, elements: vector(type0, $llvm-i1-type)),
                  parameter-types: vector(type0, type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.stackprotector"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type, make(<llvm-pointer-type>, pointee: $llvm-i8*-type)),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.stackprotector",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.stackprotectorcheck"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector(make(<llvm-pointer-type>, pointee: $llvm-i8*-type)),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.stackprotectorcheck",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.stackrestore"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.stackrestore",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.stacksave"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-i8*-type,
                  parameter-types: vector(),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.stacksave",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.trap"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector(),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.trap",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.trunc"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         let name = format-to-string("llvm.trunc.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: type0,
                  parameter-types: vector(type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readonly-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.uadd.with.overflow"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         llvm-constrain-type(type0, llvm-value-type(arguments[1]));
         let name = format-to-string("llvm.uadd.with.overflow.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: make(<llvm-struct-type>, elements: vector(type0, $llvm-i1-type)),
                  parameter-types: vector(type0, type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.umul.with.overflow"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         llvm-constrain-type(type0, llvm-value-type(arguments[1]));
         let name = format-to-string("llvm.umul.with.overflow.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: make(<llvm-struct-type>, elements: vector(type0, $llvm-i1-type)),
                  parameter-types: vector(type0, type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.usub.with.overflow"]
    := method (arguments)
         let type0 = make(<llvm-opaque-type>);
         llvm-constrain-type(type0, llvm-value-type(arguments[0]));
         llvm-constrain-type(type0, llvm-value-type(arguments[1]));
         let name = format-to-string("llvm.usub.with.overflow.%s", intrinsic-type-name(type0));

         let function-type
           = make(<llvm-function-type>,
                  return-type: make(<llvm-struct-type>, elements: vector(type0, $llvm-i1-type)),
                  parameter-types: vector(type0, type0),
                  varargs?: #f);
         make(<llvm-function>,
              name: name,
              type: make(<llvm-pointer-type>, pointee: function-type),
              attribute-list: $llvm-intrinsic-readnone-attribute-list,
              linkage: #"external");
       end;

  $llvm-intrinsic-makers["llvm.va_copy"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type, $llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.va_copy",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.va_end"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.va_end",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.var.annotation"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type, $llvm-i8*-type, $llvm-i8*-type, $llvm-i32-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.var.annotation",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.va_start"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8*-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.va_start",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

  $llvm-intrinsic-makers["llvm.x86.int"]
    := begin
         let function-type
           = make(<llvm-function-type>,
                  return-type: $llvm-void-type,
                  parameter-types: vector($llvm-i8-type),
                  varargs?: #f);
         let function
           = make(<llvm-function>,
                  name: "llvm.x86.int",
                  type: make(<llvm-pointer-type>, pointee: function-type),
                  attribute-list: $llvm-intrinsic-default-attribute-list,
                  linkage: #"external");
         method (arguments) function end
       end;

end;
