PageRenderTime 33ms CodeModel.GetById 16ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/src/wrappers/llvm/library/llvm_builder.e

http://github.com/tybor/Liberty
Specman e | 1148 lines | 668 code | 124 blank | 356 comment | 12 complexity | dda55d99dc80970956936d6d86911cfc MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1class LLVM_BUILDER
   2	-- An instruction builder represents point within an LLVM_BASIC_BLOCK where it builds instructions.
   3	
   4	-- TODO: many preconditions requires its arguments to be of a specific type
   5	-- (most often integers, floating point numbers or vectors of integers or
   6	-- floats). Replace them - if possible - with more specific types of
   7	-- arguments.  
   8	-- Note: Internally it uses the C interface so it doesn't has full-fledged
   9	-- access to the entire C++ API.
  10
  11inherit 
  12	C_STRUCT redefine default_create end 
  13		ARRAYED_COLLECTION_HANDLER redefine default_create end
  14
  15insert CORE_EXTERNALS redefine default_create end 
  16create {ANY} in_context, default_create, at_end_of
  17feature {ANY} -- Creation
  18	in_context (a_context: LLVM_CONTEXT)
  19		-- Create an LLVM_BUILDER in `a_context'.
  20	require a_context/=Void
  21	do
  22		from_external_pointer(llvmcreate_builder_in_context(a_context.handle))
  23	end
  24
  25	default_create
  26		do
  27			from_external_pointer(llvmcreate_builder)
  28		end
  29
  30	at_end_of (a_block: LLVM_BASIC_BLOCK)
  31		-- Create a new builder positioned at the end of `a_block'; this
  32		-- commodity creation feature is a shortcut for (equivalent to) "create
  33		-- Result; Result.position_at_end_of(a_block)"
  34	require a_block/=Void
  35	do
  36		default_create
  37		position_at_end_of(a_block)
  38	end
  39
  40feature {ANY} -- Positioning
  41	set_position (a_block: LLVM_BASIC_BLOCK; an_instruction: LLVM_VALUE)
  42		-- TODO: description
  43	require
  44		a_block/=Void
  45		an_instruction/=Void
  46	do
  47		llvmposition_builder(handle,a_block.handle,an_instruction.handle)
  48	end
  49
  50	position_before (an_instruction: LLVM_INSTRUCTION)
  51		-- Set Current position before `an_instruction'
  52	require an_instruction/=Void
  53	do
  54		llvmposition_builder_before(handle,an_instruction.handle)
  55	end
  56	
  57	position_at_end_of (a_block: LLVM_BASIC_BLOCK)
  58		-- Set Current position at the end of `a_block'
  59	require a_block/=Void
  60	do
  61		llvmposition_builder_at_end(handle,a_block.handle)
  62	end
  63
  64	insert_block: LLVM_BASIC_BLOCK
  65	local p: POINTER
  66	do
  67		p := llvmget_insert_block(handle)
  68		if p.is_not_null then create Result.from_external_pointer(p) end
  69	end
  70
  71	clear_insertion_position
  72		do
  73			llvmclear_insertion_position(handle)
  74		end
  75
  76	insert_instruction (an_instruction: LLVM_INSTRUCTION)
  77	require an_instruction/=Void
  78	do
  79		llvminsert_into_builder(handle,an_instruction.handle)
  80	end
  81
  82	insert_with_name (a_value: LLVM_VALUE; a_name: ABSTRACT_STRING)
  83	require 
  84		a_value/=Void
  85		a_name/=Void
  86	do
  87		llvminsert_into_builder_with_name(handle,a_value.handle,a_name.to_external)
  88	end
  89feature {ANY} -- Terminators 
  90	return_void: LLVM_RETURN_INST
  91		do
  92			create Result.from_external_pointer(llvmbuild_ret_void(handle))
  93		end
  94	
  95	return (a_value: LLVM_VALUE): LLVM_RETURN_INST
  96		-- A "ret" instruction returing `a_value'
  97	require a_value/=Void
  98	do
  99		create Result.from_external_pointer(llvmbuild_ret(handle,a_value.handle))
 100	ensure Result/=Void
 101	end
 102	
 103	aggregate_return (some_values: COLLECTION[LLVM_VALUE]): LLVM_RETURN_INST
 104		-- A "ret" instruction returning `some_values'.
 105	require some_values/=Void; not some_values.is_empty
 106	local sv: FAST_ARRAY[POINTER]; i: ITERATOR[LLVM_VALUE]
 107	do
 108		create sv.with_capacity(some_values.count)
 109		from i:=some_values.new_iterator; i.start 
 110		until i.is_off loop
 111			sv.add_last(i.item.handle); i.next
 112		end
 113		create Result.from_external_pointer
 114		(llvmbuild_aggregate_ret(handle,sv.to_external,some_values.count.to_natural_32))
 115	ensure Result/=Void
 116	end
 117	
 118	unconditional_branch (a_destination: LLVM_BASIC_BLOCK): LLVM_BRANCH_INST
 119		-- An unconditional branch "br" instruction that transfer the control
 120		-- flow to a different basic block in the current function.
 121	require a_destination/=Void
 122	do
 123		create Result.from_external_pointer(llvmbuild_br(handle,a_destination.handle))
 124	ensure Result/=Void
 125	end
 126
 127	conditional_branch (an_if: LLVM_VALUE; a_then, an_else: LLVM_BASIC_BLOCK): LLVM_BRANCH_INST
 128		-- A conditional branch "br" instruction that will pass control flow to
 129		-- `a_then' if `an_if' evaluates to True, to `an_else' otherwise
 130	require 
 131		an_if/=Void
 132		a_then/=Void
 133		an_else/=Void
 134	do
 135		create Result.from_external_pointer (llvmbuild_cond_br
 136		(handle, an_if.handle, a_then.handle, an_else.handle))
 137	ensure Result/=Void
 138	end
 139
 140	switch (a_value: LLVM_VALUE; an_else: LLVM_BASIC_BLOCK; a_number_of_cases: NATURAL_32): LLVM_SWITCH_INST
 141		-- A 'switch' instruction, used to transfer control flow to one of
 142		-- several different places. It is a generalization of the 'br'
 143		-- instruction, allowing a branch to occur to one of many possible
 144		-- destinations. `an_else' is executed when `a_value' will not match
 145		-- one of the cases added later with `add_case' which must be exactly
 146		-- `a_number_of_cases'.
 147	require 
 148		a_value/=Void
 149		an_else/=Void
 150	do
 151		create Result.from_external_pointer
 152		(llvmbuild_switch(handle,a_value.handle,an_else.handle,a_number_of_cases))
 153	ensure Result/=Void
 154	end
 155
 156	invoke (a_function: LLVM_FUNCTION_TYPE; some_arguments: COLLECTION[LLVM_VALUE]; a_then, a_catch: LLVM_BASIC_BLOCK; a_name: ABSTRACT_STRING): LLVM_INVOKE_INST
 157		-- An "invoke" instruction. If `a_function' is parameterless `some_arguments' is not used and can be Void. 
 158		-- TODO: specify the meaning of `a_then' and `a_catch'.
 159		require
 160			a_function/=Void
 161			a_then/=Void
 162			a_catch/=Void
 163			a_name/=Void
 164			some_arguments=Void implies a_function.parameters_count=0
 165			some_arguments/=Void implies a_function.parameters_count>0 and not some_arguments.is_empty
 166		local args: FAST_ARRAY[POINTER]; args_p: POINTER
 167		do
 168			if some_arguments/=Void and then not some_arguments.is_empty then
 169				args:=collection_to_c_array(some_arguments)
 170				args_p := args.to_external
 171			end
 172			create Result.from_external_pointer
 173			(llvmbuild_invoke(handle,a_function.handle,
 174			args_p,args.count.to_natural_32,
 175			a_then.handle,a_catch.handle, a_name.to_external))
 176		ensure Result/=Void
 177		end
 178
 179	unreachable: LLVM_VALUE
 180		-- A newly create 'unreachable' instruction; it has no defined
 181		-- semantics. This instruction is used to inform the optimizer that a
 182		-- particular portion of the code is not reachable. This can be used to
 183		-- indicate that the code after a no-return function cannot be reached,
 184		-- and other facts.
 185	do
 186		create Result.from_external_pointer (llvmbuild_unreachable(handle))
 187	ensure Result/=Void
 188	end
 189
 190feature {ANY} -- Arithmetic
 191	add (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 192		-- A newly created `add' instruction with `a_name' summing `a_left' and `a_right'.
 193		-- The two arguments to the 'add' instruction must be integer or vector
 194		-- of integer values. Both arguments must have identical types.
 195		
 196		-- If the sum has unsigned overflow, the result returned is the
 197		-- mathematical result modulo 2n, where n is the bit width of the
 198		-- result.
 199
 200		-- Because LLVM integers use a two's complement representation, this
 201		-- instruction is appropriate for both signed and unsigned integers.
 202
 203		-- The "nuw" and "nsw" variant of this instruction stand for "No
 204		-- Unsigned Wrap" and "No Signed Wrap", respectively. If the nuw and/or
 205		-- nsw keywords are present, the result value of the add is undefined
 206		-- if unsigned and/or signed overflow, respectively, occurs.
 207	require 
 208		a_left/=Void
 209		a_right/=Void
 210		a_name/=Void
 211		identical_type: a_left.type ~ a_right.type 
 212		integers_or_vectors: a_left.type.is_integer or a_left.is_constant_vector
 213		vectors_are_of_integers: a_left.is_constant_vector implies a_left.as_constant_vector.type.element_type.is_integer
 214		do
 215			create Result.from_external_pointer
 216			(llvmbuild_add(handle,a_left.handle, a_right.handle, a_name.to_external))
 217		ensure 
 218			Result/=Void
 219			Result.type ~ a_left.type 
 220		end
 221
 222	no_signed_wrap_addition, nsw_add (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_ADD_OPERATOR
 223		-- A newly created `no-signed-wrap-add' instruction with `a_name' summing `a_left' and `a_right'. See `add' for further informations.
 224	require 
 225		a_left/=Void
 226		a_right/=Void
 227		a_name/=Void
 228		identical_type: a_left.type ~ a_right.type 
 229		integers_or_vectors: a_left.type.is_integer or a_left.is_constant_vector
 230		vectors_are_of_integers: a_left.is_constant_vector implies a_left.as_constant_vector.type.element_type.is_integer
 231	do
 232		create Result.from_external_pointer
 233		(llvmbuild_nswadd(handle,a_left.handle,a_right.handle,a_name.to_external))
 234	ensure
 235		Result/=Void
 236		Result.type ~ a_left.type 
 237	end
 238
 239	float_add, fadd (a_left,a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 240		-- The 'fadd' instruction returns the sum of its two operands that must
 241		-- be floating point or vector of floating point values and must have
 242		-- identical types. The value produced is the floating point sum of the
 243		-- two operands.
 244	require
 245		a_left/=Void
 246		a_right/=Void
 247		a_name/=Void
 248		identical_type: a_left.type ~ a_right.type 
 249		floating_points_or_vectors: a_left.is_constant_fp or a_left.is_constant_vector
 250		vectors_are_of_floats: a_left.is_constant_vector implies a_left.as_constant_vector.type.element_type.is_floating_point
 251	do
 252		create Result.from_external_pointer
 253		(llvmbuild_fadd(handle,a_left.handle,a_right.handle,a_name.to_external))
 254	ensure 
 255		Result/=Void
 256		Result.type ~ a_left.type 
 257	end
 258	
 259	sub (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_SUB_OPERATOR
 260		-- An integer subtraction operation on `a_left' and `a_right'.
 261	require 
 262		a_left/=Void
 263		a_right/=Void
 264		identical_type: a_left.type ~ a_right.type 
 265		integers_or_vectors: a_left.type.is_integer or a_left.is_constant_vector
 266		vectors_are_of_integers: a_left.is_constant_vector implies a_left.as_constant_vector.type.element_type.is_integer
 267	do
 268		create Result.from_external_pointer(llvmbuild_sub(handle,a_left.handle,a_right.handle,a_name.to_external))
 269	ensure
 270		Result/=Void
 271		Result.type ~ a_left.type 
 272	end
 273
 274	mul (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 275		-- Create a 'mul' instruction that multiplyies `a_left' and `a_right', with `a_name'. 
 276
 277		-- If the result of the multiplication has unsigned overflow, the
 278		-- result returned is the mathematical result modulo 2n, where n is the
 279		-- bit width of the result.
 280
 281		-- Because LLVM integers use a two's complement representation, and the
 282		-- result is the same width as the operands, this instruction returns
 283		-- the correct result for both signed and unsigned integers. If a full
 284		-- product (e.g. i32xi32->i64) is needed, the operands should be
 285		-- sign-extended or zero-extended as appropriate to the width of the
 286		-- full product.
 287
 288		-- nuw and nsw variants stand for "No Unsigned Wrap" and "No Signed
 289		-- Wrap", respectively. If the nuw and/or nsw keywords are present, the
 290		-- result value of the mul is undefined if unsigned and/or signed
 291		-- overflow, respectively, occurs.
 292	require 
 293		a_left/=Void
 294		a_right/=Void
 295		a_name/=Void
 296		identical_type: a_left.type ~ a_right.type 
 297		integers_or_vectors: a_left.type.is_integer or a_left.is_constant_vector
 298		vectors_are_of_integers: a_left.is_constant_vector implies a_left.as_constant_vector.type.element_type.is_integer
 299	do
 300		create Result.from_external_pointer
 301		(llvmbuild_mul(handle,a_left.handle, a_right.handle, a_name.to_external))
 302	ensure 
 303		Result/=Void
 304		Result.type ~ a_left.type 
 305	end
 306
 307	float_multiplication, fmul (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 308		-- The product of `a_left' and `a_right', labelled with `a_name'
 309	require
 310		a_left/=Void
 311		a_right/=Void
 312		a_name/=Void
 313		identical_type: a_left.type ~ a_right.type 
 314		floating_points_or_vectors: a_left.is_constant_fp or a_left.is_constant_vector
 315		vectors_are_of_floats: a_left.is_constant_vector implies a_left.as_constant_vector.type.element_type.is_floating_point
 316	do
 317		create Result.from_external_pointer(llvmbuild_fmul(handle,a_left.handle,a_right.handle, a_name.to_external))
 318	ensure 
 319		Result/=Void
 320		Result.type ~ a_left.type 
 321	end
 322
 323	udiv, unsigned_division (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 324		-- The unsigned integer quotient of `a_left' divided by `a_right'. 
 325
 326		-- Note that unsigned integer division and signed integer division are
 327		-- distinct operations; for signed integer division, use 'sdiv'.
 328
 329		-- Division by zero leads to undefined behavior.
 330	require 
 331		a_left/=Void
 332		a_right/=Void
 333		a_name/=Void
 334		identical_type: a_left.type ~ a_right.type 
 335		integers_or_vectors: a_left.type.is_integer or a_left.is_constant_vector
 336		vectors_are_of_integers: a_left.is_constant_vector implies a_left.as_constant_vector.type.element_type.is_integer
 337	do
 338		create Result.from_external_pointer(llvmbuild_udiv(handle,a_left.handle,a_right.handle,a_name.to_external)) 
 339	ensure 
 340		Result/=Void
 341		Result.type ~ a_left.type 
 342	end
 343
 344	signed_division (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 345		-- The signed integer quotient of `a_left' and `a_right' rounded towards zero.
 346
 347		-- Note that signed integer division and unsigned integer division are
 348		-- distinct operations; for unsigned integer division, use 'udiv'.
 349
 350		-- Division by zero leads to undefined behavior. Overflow also leads to
 351		-- undefined behavior; this is a rare case, but can occur, for example,
 352		-- by doing a 32-bit division of -2147483648 by -1.
 353
 354		-- TODO: If the exact keyword is present, the result value of the sdiv
 355		-- is undefined if the result would be rounded or if overflow would
 356		-- occur.
 357	require 
 358		a_left/=Void
 359		a_right/=Void
 360		a_name/=Void
 361		identical_type: a_left.type ~ a_right.type 
 362		integers_or_vectors: a_left.type.is_integer or a_left.is_constant_vector
 363		vectors_are_of_integers: a_left.is_constant_vector implies a_left.as_constant_vector.type.element_type.is_integer
 364	do
 365		create Result.from_external_pointer(llvmbuild_udiv(handle,a_left.handle,a_right.handle,a_name.to_external)) 
 366	ensure 
 367		Result/=Void
 368		Result.type ~ a_left.type 
 369	end
 370
 371	exact_signed_division (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 372		-- An "exact sdiv" operation, the exact, signed integer quotient of
 373		-- `a_left' and `a_right' rounded towards zero.
 374
 375		-- The result value of the sdiv is undefined if the result would be
 376		-- rounded or if overflow would occur.
 377	require 
 378		a_left/=Void
 379		a_right/=Void
 380		a_name/=Void
 381		identical_type: a_left.type ~ a_right.type 
 382		integers_or_vectors: a_left.type.is_integer or a_left.is_constant_vector
 383		vectors_are_of_integers: a_left.is_constant_vector implies a_left.as_constant_vector.type.element_type.is_integer
 384	do
 385		create Result.from_external_pointer(llvmbuild_exact_sdiv(handle,a_left.handle,a_right.handle,a_name.to_external))
 386	ensure 
 387		Result/=Void
 388		Result.type ~ a_left.type 
 389	end
 390	
 391	float_division  (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 392		-- An 'fdiv' instruction, the floating point quotient of `a_left' and `a_right'.
 393	require
 394		a_left/=Void
 395		a_right/=Void
 396		a_name/=Void
 397		identical_type: a_left.type ~ a_right.type 
 398		floating_points_or_vectors: a_left.is_constant_fp or a_left.is_constant_vector
 399		vectors_are_of_floats: a_left.is_constant_vector implies a_left.as_constant_vector.type.element_type.is_floating_point
 400	do
 401		create Result.from_external_pointer(llvmbuild_fdiv(handle,a_left.handle,a_right.handle, a_name.to_external))
 402	ensure 
 403		Result/=Void
 404		Result.type ~ a_left.type 
 405	end
 406
 407	unsigned_remainder (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 408		-- A 'urem' instruction computing the unsigned integer remainder of the
 409		-- unsigned division of `a_left' and `a_right'.To get the remainder an
 410		-- unsigned division is always performed.
 411
 412		-- Note that unsigned integer remainder and signed integer remainder
 413		-- are distinct operations; for signed integer remainder, use `srem'.
 414
 415		-- Taking the remainder of a division by zero leads to undefined behavior.
 416	require 
 417		a_left/=Void
 418		a_right/=Void
 419		a_name/=Void
 420		identical_type: a_left.type ~ a_right.type 
 421		integers_or_vectors_of_integers: a_left.type.is_integer or else a_left.is_constant_vector and then a_left.as_constant_vector.type.element_type.is_integer
 422	do
 423		create Result.from_external_pointer(llvmbuild_urem(handle,a_left.handle,a_right.handle,a_name.to_external))
 424	ensure
 425		Result/=Void
 426		Result.type ~ a_left.type 
 427	end
 428
 429	signed_remainder (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 430		-- A 'srem' instruction computing the signed integer remainder of the
 431		-- signed division of `a_left' and `a_right'.To get the remainder an
 432		-- signed division is always performed.
 433
 434		-- This instruction returns the remainder of a division (where the
 435		-- result has the same sign as the dividend, `a_left'), not the modulo
 436		-- operator (where the result has the same sign as the divisor,
 437		-- 'a_right') of a value. For more information about the difference,
 438		-- see The Math Forum. For a table of how this is implemented in
 439		-- various languages, please see
 440		-- http://en.wikipedia.org/wiki/Modulo_operation
 441
 442		-- Note that signed integer remainder and unsigned integer remainder
 443		-- are distinct operations; for unsigned integer remainder, use `urem'.
 444
 445		-- Taking the remainder of a division by zero leads to undefined
 446		-- behavior. Overflow also leads to undefined behavior; this is a rare
 447		-- case, but can occur, for example, by taking the remainder of a
 448		-- 32-bit division of -2147483648 by -1. (The remainder doesn't
 449		-- actually overflow, but this rule lets srem be implemented using
 450		-- instructions that return both the result of the division and the
 451		-- remainder.)	
 452		
 453		-- Note that unsigned integer remainder and signed integer remainder
 454		-- are distinct operations; for signed integer remainder, use `srem'.
 455	require 
 456		a_left/=Void
 457		a_right/=Void
 458		a_name/=Void
 459		identical_type: a_left.type ~ a_right.type 
 460		integers_or_vectors_of_integers: a_left.type.is_integer or else a_left.is_constant_vector and then a_left.as_constant_vector.type.element_type.is_integer
 461	do
 462		create Result.from_external_pointer(llvmbuild_srem(handle,a_left.handle,a_right.handle,a_name.to_external))
 463	ensure
 464		Result/=Void
 465		Result.type ~ a_left.type 
 466	end
 467
 468	float_remainder (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 469		-- An 'frem' instruction computing the remainder of the division of `a_left' and `a_right'.
 470		-- The remainder has the same sign as the dividend.
 471	require
 472		a_left/=Void
 473		a_right/=Void
 474		a_name/=Void
 475		identical_type: a_left.type ~ a_right.type 
 476		floating_points_or_vectors_of_floats: a_left.is_constant_fp or else a_left.is_constant_vector and then a_left.as_constant_vector.type.element_type.is_floating_point
 477	do
 478		create Result.from_external_pointer(llvmbuild_frem(handle,a_left.handle,a_right.handle,a_name.to_external))
 479	ensure
 480		Result/=Void
 481		Result.type ~ a_left.type 
 482	end		
 483
 484	shift_left (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 485		-- A 'shl' instruction that computes `a_left' shifted to the left by a number of bits specified in `a_right'.
 486
 487		-- The value produced is op1 * 2op2 mod 2n, where n is the width of the result. If op2 is (statically or dynamically) negative or equal to or larger than the number of bits in op1, the result is undefined. If the arguments are vectors, each vector element of op1 is shifted by the corresponding shift amount in op2.
 488	require 
 489		a_left/=Void
 490		a_right/=Void
 491		a_name/=Void
 492		identical_type: a_left.type ~ a_right.type 
 493		integers_or_vectors_of_integers: a_left.type.is_integer or else a_left.is_constant_vector and then a_left.as_constant_vector.type.element_type.is_integer
 494	do
 495		create Result.from_external_pointer(llvmbuild_shl(handle,a_left.handle,a_right.handle,a_name.to_external)) 
 496	ensure
 497		Result/=Void
 498		Result.type ~ a_left.type 
 499	end
 500	
 501	logical_shift_right (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 502		-- A "lshr" instruction (logical shift right), computing `a_left' shifted to the right by the number of bits specified in `a_right' with zero fill.
 503
 504		-- This instruction always performs a logical shift right operation.
 505		-- The most significant bits of the result will be filled with zero
 506		-- bits after the shift. If op2 is (statically or dynamically) equal to
 507		-- or larger than the number of bits in op1, the result is undefined.
 508		-- If the arguments are vectors, each vector element of op1 is shifted
 509		-- by the corresponding shift amount in op2.
 510	require 
 511		a_left/=Void
 512		a_right/=Void
 513		a_name/=Void
 514		identical_type: a_left.type ~ a_right.type 
 515		integers_or_vectors_of_integers: a_left.type.is_integer or else a_left.is_constant_vector and then a_left.as_constant_vector.type.element_type.is_integer
 516	do
 517		create Result.from_external_pointer(llvmbuild_lshr(handle,a_left.handle,a_right.handle,a_name.to_external)) 
 518	ensure
 519		Result/=Void
 520		Result.type ~ a_left.type 
 521	end
 522
 523	arithmetic_shift_right (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 524		-- An "ashr" instruction (arithmetic shift right), computing `a_left shifted to the right by the number of bits specified in `a_right' with sign extension. `a_right' is treated as an unsigned value. 
 525
 526		-- This instruction always performs an arithmetic shift right operation, The most significant bits of the result will be filled with the sign bit of `a_left'. If `a_right' is (statically or dynamically) equal to or larger than the number of bits in `a_left', the result is undefined. If the arguments are vectors, each vector element of `a_left' is shifted by the corresponding shift amount in 'a_right'.
 527		require 
 528		a_left/=Void
 529		a_right/=Void
 530		a_name/=Void
 531		identical_type: a_left.type ~ a_right.type 
 532		integers_or_vectors_of_integers: a_left.type.is_integer or else a_left.is_constant_vector and then a_left.as_constant_vector.type.element_type.is_integer
 533	do
 534		create Result.from_external_pointer(llvmbuild_ashr(handle,a_left.handle,a_right.handle,a_name.to_external)) 
 535	ensure
 536		Result/=Void
 537		Result.type ~ a_left.type 
 538	end
 539
 540feature {ANY} -- Logical operators
 541	logical_and (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 542		-- An "and" instruction, the bitwise logical and of `a_left' and `a_right'.
 543		require 
 544		a_left/=Void
 545		a_right/=Void
 546		a_name/=Void
 547		identical_type: a_left.type ~ a_right.type 
 548		integers_or_vectors_of_integers: a_left.type.is_integer or else a_left.is_constant_vector and then a_left.as_constant_vector.type.element_type.is_integer
 549		do
 550			create Result.from_external_pointer(llvmbuild_and(handle,a_left.handle,a_right.handle,a_name.to_external))
 551	ensure
 552		Result/=Void
 553		Result.type ~ a_left.type 
 554	end
 555
 556	logical_or (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 557		-- An "or" instruction, the bitwise logical or of `a_left' and `a_right'.
 558		require 
 559		a_left/=Void
 560		a_right/=Void
 561		a_name/=Void
 562		identical_type: a_left.type ~ a_right.type 
 563		integers_or_vectors_of_integers: a_left.type.is_integer or else a_left.is_constant_vector and then a_left.as_constant_vector.type.element_type.is_integer
 564		do
 565			create Result.from_external_pointer(llvmbuild_or(handle,a_left.handle,a_right.handle,a_name.to_external))
 566	ensure
 567		Result/=Void
 568		Result.type ~ a_left.type 
 569	end
 570		
 571	logical_xor (a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 572		-- A "xor" instruction, the bitwise exclusive logical or of `a_left' and `a_right'.
 573		require 
 574		a_left/=Void
 575		a_right/=Void
 576		a_name/=Void
 577		identical_type: a_left.type ~ a_right.type 
 578		integers_or_vectors_of_integers: a_left.type.is_integer or else a_left.is_constant_vector and then a_left.as_constant_vector.type.element_type.is_integer
 579		do
 580			create Result.from_external_pointer(llvmbuild_xor(handle,a_left.handle,a_right.handle,a_name.to_external))
 581	ensure
 582		Result/=Void
 583		Result.type ~ a_left.type 
 584	end
 585	
 586	logical_neg (a_value: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 587		-- TODO: provide description, semating, preconditions and postconditions.
 588	require a_value/=Void
 589 	do
 590		create Result.from_external_pointer(llvmbuild_neg(handle,a_value.handle,a_name.to_external))
 591	ensure Result/=Void
 592	end
 593	
 594	logical_not (a_value: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_VALUE
 595		-- TODO: provide description, semating, preconditions and postconditions.
 596	require a_value/=Void
 597 	do
 598		create Result.from_external_pointer(llvmbuild_not(handle,a_value.handle, a_name.to_external))
 599	ensure Result/=Void
 600	end
 601
 602feature {ANY} -- Memory
 603	malloc_inst (a_type: LLVM_TYPE; a_name: ABSTRACT_STRING): LLVM_MALLOC_INST
 604		-- A 'malloc' instruction allocating memory for `a_type' on the system heap and returning a pointer to it. The object is always allocated in the generic address space (address space zero). Memory is allocated using the system "malloc" function, and a pointer is returned. The result of a zero byte allocation is undefined. The result is null if there is insufficient memory available.
 605
 606		-- TODO: LLVM assembly language allows to specify the alignment of the allocation but I coudln't figure how to implement if using the C bindings we are relying on. 
 607	require
 608		a_type/=Void
 609		-- TODO type must be sized
 610	do
 611		create Result.from_external_pointer(llvmbuild_malloc(handle, a_type.handle,a_name.to_external))
 612	ensure Result/=Void
 613	end
 614
 615
 616	array_malloc (a_type: LLVM_TYPE; a_number: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_MALLOC_INST
 617		-- A 'malloc' instruction allocateing memory from the system heap for
 618		-- `a_number' of objects of `a_type' returing a pointer to it. The
 619		-- object is always allocated in the generic address space (address
 620		-- space zero). The result of a zero byte allocation is undefined. The
 621		-- result is null if there is insufficient memory available.
 622	require
 623		a_type/=Void
 624		-- TODO type must be sized
 625		a_number/=Void
 626		a_number.type.is_integer
 627		a_name/=Void
 628	do
 629		create Result.from_external_pointer(llvmbuild_array_malloc(handle,a_type.handle, a_number.handle, a_name.to_external))
 630	ensure
 631		Result/=Void
 632	end
 633
 634	alloca_inst (a_type: LLVM_TYPE; a_name: ABSTRACT_STRING): LLVM_ALLOCA_INST
 635		-- An "alloca" instruction allocating memory for an instance of
 636		-- `a_type' on the stack frame of the currently executing function, to
 637		-- be automatically released when this function returns to its caller.
 638		-- The object is always allocated in the generic address space (address
 639		-- space zero).
 640
 641		-- The operation is undefined if there is insufficient stack space for
 642		-- the allocation. 'alloca'd memory is automatically released when the
 643		-- function returns. The 'alloca' instruction is commonly used to
 644		-- represent automatic variables that must have an address available.
 645		-- When the function returns (either with the ret or unwind
 646		-- instructions), the memory is reclaimed. Allocating zero bytes is
 647		-- legal, but the result is undefined.
 648	require 
 649		a_type/=Void
 650		-- TODO: a_type.is_sized
 651	do
 652		create Result.from_external_pointer(llvmbuild_alloca(handle,a_type.handle,a_name.to_external))
 653	ensure	
 654		Result/=Void
 655	end
 656
 657	array_alloca (a_type: LLVM_TYPE; a_number: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_ALLOCA_INST
 658		-- An "alloca" instruction allocating memory for `a_number' of instances of
 659		-- `a_type' on the stack frame of the currently executing function, to
 660		-- be automatically released when this function returns to its caller.
 661		-- See `alloca' for further informations.
 662	require 
 663		a_type/=Void
 664		-- TODO: a_type.is_sized
 665		a_number/=Void
 666		a_number.type.is_integer
 667	do
 668		create Result.from_external_pointer(llvmbuild_array_alloca(handle,a_type.handle,a_number.handle,a_name.to_external))
 669	ensure
 670		Result/=Void
 671	end
 672
 673	llvm_free (a_value: LLVM_VALUE): LLVM_FREE_INST
 674		-- A 'free' instruction returning memory back to the unused memory heap
 675		-- to be reallocated in the future.
 676
 677		-- Access to the memory pointed to by the pointer is no longer defined
 678		-- after this instruction executes. If the pointer is null, the
 679		-- operation is a noop.
 680	require
 681		a_value/=Void
 682		a_value.type.is_pointer
 683		-- TODO: a value was allocated with a 'malloc' instruction
 684	do
 685		create Result.from_external_pointer(llvmbuild_free(handle, a_value.handle))
 686	ensure Result/=Void
 687	end
 688
 689 	load (a_location: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_LOAD_INST
 690		-- A 'load' instruction that will read from memory `a_location' that
 691		-- specifies the memory address from which to load.
 692	
 693		-- TODO: LLVM allows to mark the load as volatile; this is currently
 694		-- not supported. If the load is marked as volatile, then the optimizer
 695		-- is not allowed to modify the number or order of execution of this
 696		-- load with other volatile load and store instructions.
 697 
 698		-- Semantics: The location of memory pointed to is loaded. If the value
 699		-- being loaded is of scalar type then the number of bytes read does
 700		-- not exceed the minimum number of bytes needed to hold all bits of
 701		-- the type. For example, loading an i24 reads at most three bytes.
 702		-- When loading a value of a type like i20 with a size that is not an
 703		-- integral number of bytes, the result is undefined if the value was
 704		-- not originally written using a store of the same type.
 705	require 
 706		a_location/=Void
 707		-- TODO: a_location.is_pointer
 708		-- TODO: The pointer must point to a first class type. 
 709	do
 710		create Result.from_external_pointer(llvmbuild_load(handle,a_location.handle,a_name.to_external))
 711	ensure Result/=Void
 712	end
 713
 714	store (a_value: LLVM_VALUE; a_pointer: LLVM_VALUE): LLVM_STORE_INST
 715		-- A 'store' instruction that will update memory at `an_address' to
 716		-- contain `a_value'. 
 717		
 718		-- If `a_value' is of scalar type then the number of bytes written does
 719		-- not exceed the minimum number of bytes needed to hold all bits of
 720		-- the type. For example, storing an i24 writes at most three bytes.
 721		-- When writing a value of a type like i20 with a size that is not an
 722		-- integral number of bytes, it is unspecified what happens to the
 723		-- extra bits that do not belong to the type, but they will typically
 724		-- be overwritten. 
 725
 726		-- TODO: volatile store is currently not supported so the following
 727		-- does not apply. If the store is marked as volatile, then the
 728		-- optimizer is not allowed to modify the number or order of execution
 729		-- of this store with other volatile load and store instructions.
 730
 731		-- TODO: LLVM support specific alignement but it is currently not provided. The following does not apply.The optional constant "align" argument specifies the alignment of the operation (that is, the alignment of the memory address). A value of 0 or an omitted "align" argument means that the operation has the preferential alignment for the target. It is the responsibility of the code emitter to ensure that the alignment information is correct. Overestimating the alignment results in an undefined behavior. Underestimating the alignment may produce less efficient code. An alignment of 1 is always safe.
 732	require
 733		a_value/=Void
 734		a_pointer/=Void
 735		-- TODO: a_pointer.is_pointer 
 736		-- TODO: a_pointer must be a pointer to the same type of a_value which must be a first class type.
 737	do
 738		create Result.from_external_pointer(llvmbuild_store(handle,a_value.handle,a_pointer.handle))
 739	ensure	
 740		Result/=Void
 741	end
 742
 743	get_element_pointer (a_pointer: LLVM_VALUE; some_indices: COLLECTION[LLVM_VALUE]; a_name: ABSTRACT_STRING): LLVM_GEP_OPERATOR
 744		-- A "get element pointer" intruction 
 745
 746	require
 747		-- TODO: a_pointer should point to what?
 748		a_name/=Void
 749	local indices: FAST_ARRAY[POINTER]
 750	do
 751		-- Intentionally avoiding WRAPPER_COLLECTION to avoid tricks with native arrays
 752		indices := collection_to_c_array(some_indices)
 753		create Result.from_external_pointer(llvmbuild_gep(handle, a_pointer.handle, indices.to_external, some_indices.count.to_natural_32, a_name.to_external))
 754	ensure Result/=Void
 755	end
 756	
 757
 758	-- TODO: wrap LLVMValueRef LLVMBuildInBoundsGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
 759	--                                   LLVMValueRef *Indices, unsigned NumIndices,
 760	--                                   const char *Name);
 761
 762	get_struct_element_pointer (a_pointer: LLVM_VALUE; an_index: NATURAL_32; a_name: ABSTRACT_STRING): LLVM_GEP_OPERATOR
 763		-- "getelementpointer" of a structure field
 764	require 
 765		-- TODO: a_pointer should point to a struct
 766		a_name/=Void
 767	do
 768		-- LLVMValueRef LLVMBuildStructGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
 769		--                                 unsigned Idx, const char *Name);
 770		create Result.from_external_pointer(llvmbuild_struct_gep(handle,a_pointer.handle, an_index, a_name.to_external))
 771	ensure 
 772		Result/=Void
 773	end
 774
 775	global_string (a_string, a_name: ABSTRACT_STRING): LLVM_GLOBAL_VARIABLE
 776		-- A global string with the content of `a_string' referrable by `a_name'.
 777	do
 778		create Result.from_external_pointer(llvmbuild_global_string
 779		(handle,a_string.to_external, a_name.to_external))
 780	ensure
 781		Result/=Void
 782	end
 783
 784	-- TODO: discover the difference between LLVMBuildGlobalString and LLVMBuildGlobalStringPtr from Liberty point of view.
 785
 786	-- LLVMValueRef LLVMBuildGlobalStringPtr(LLVMBuilderRef B, const char *Str,
 787	--                                       const char *Name);
 788	-- 
 789feature {ANY} -- Casts
 790	trunc (a_value: LLVM_VALUE; a_destination_type: LLVM_INTEGER_TYPE; a_name: ABSTRACT_STRING): LLVM_TRUNC_INST
 791		-- A "trunc" instruction; `a_value' an integer type larger than
 792		-- `a_destination_type' will be truncated to the size of
 793		-- `a_destination_type'. Equal sized types are not allowed.
 794
 795		-- The "trunc" instruction truncates the high order bits in value and
 796		-- converts the remaining bits to `a_destination_type'. Since the
 797		-- source size must be larger than the destination size, "trunc" cannot
 798		-- be a no-op cast. It will always truncate bits.
 799		require 
 800			a_value/=Void
 801			value_is_integer: a_value.type.is_integer
 802			-- TODO: value_width_larger_than_destination: a_value.type
 803			a_destination_type/=Void
 804			a_name/=Void
 805		do
 806			create Result.from_external_pointer(llvmbuild_trunc(handle,a_value.handle,a_destination_type.handle,a_name.to_external))
 807		ensure 
 808			Result/=Void
 809			Result.type ~ a_destination_type
 810		end
 811
 812	zero_extend, zext (a_value: LLVM_VALUE; a_destination_type: LLVM_INTEGER_TYPE; a_name: ABSTRACT_STRING): LLVM_ZEXT_INST
 813		-- A "zext" instruction; it will fill the high order bits of `a_value' until it reaches the size of `a_destination_type'. 
 814		-- When zero extending from an "i1", the result will always be either 0 or 1.
 815		require
 816			a_value/=Void
 817			a_destination_type/=Void
 818			a_name/=Void
 819		do
 820			create Result.from_external_pointer(llvmbuild_zext(handle,a_value.handle,a_destination_type.handle,a_name.to_external))
 821		ensure
 822			Result/=Void
 823		end
 824
 825	sign_extend, sext (a_value: LLVM_VALUE; a_destination_type: LLVM_TYPE; a_label: ABSTRACT_STRING): LLVM_SEXT_INST
 826		-- A new "sext" instruction, that will sign extend `a_value' to until fits `a_destination_type'.
 827
 828		-- `a_value' must be of an integer type; also `a_destination_type' shall be of integer type.
 829		-- The bit size of the value must be smaller than the bit size of the destination type, ty2.
 830
 831		-- A "sext" instruction performs a sign extension by copying the sign
 832		-- bit (highest order bit) of the value until it reaches the bit size
 833		-- of the type ty2.
 834
 835		-- When sign extending from i1, the extension always results in -1 or 0.
 836		require
 837			a_value/=Void
 838			a_destination_type/=Void
 839			a_label/=Void
 840			--TODO a_value is an integer
 841			-- TODO: a_destination_type shall be an integer type
 842		do
 843			create Result.from_external_pointer
 844			(llvmbuild_sext(handle,a_value.handle,a_destination_type.handle,a_label.to_external))
 845		ensure Result/=Void
 846		end
 847
 848	floating_point_to_unsigned_integer, fptoui (a_value: LLVM_VALUE; a_type: LLVM_TYPE; a_label: ABSTRACT_STRING): LLVM_FPTOUI_INST
 849		-- A new "fptoui" instruction that converts the floating point `a_value' to its unsigned integer equivalent of `a_type'.
 850
 851		-- `a_value' must be a scalar or vector floating point value, and `a_type' must be an integer type. If ty is a vector floating point type, ty2 must be a vector integer type with the same number of elements as ty
 852
 853		-- The 'fptoui' instruction converts its floating point operand into the nearest (rounding towards zero) unsigned integer value. If the value cannot fit in ty2, the results are undefined.
 854	require 
 855		a_value/=Void
 856		a_type/=Void
 857		a_label/=Void
 858		float_or_float_vector: a_value.type.is_floating_point or a_value.type.is_vector and then a_value.type.as_vector.element_type.is_floating_point
 859		when_vector_destination_is_vector: a_value.type.is_vector implies a_type.is_vector and then a_value.type.as_vector.size = a_type.as_vector.size
 860	do
 861		create Result.from_external_pointer(llvmbuild_fpto_ui(handle,a_value.handle,a_type.handle,a_label.to_external))
 862	ensure Result/=Void
 863	end
 864
 865-- LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef, LLVMValueRef Val,
 866--                              LLVMTypeRef DestTy, const char *Name);
 867-- LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef, LLVMValueRef Val,
 868--                              LLVMTypeRef DestTy, const char *Name);
 869-- LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef, LLVMValueRef Val,
 870--                              LLVMTypeRef DestTy, const char *Name);
 871-- LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef, LLVMValueRef Val,
 872--                               LLVMTypeRef DestTy, const char *Name);
 873-- LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef, LLVMValueRef Val,
 874--                             LLVMTypeRef DestTy, const char *Name);
 875-- LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef, LLVMValueRef Val,
 876--                                LLVMTypeRef DestTy, const char *Name);
 877-- LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef, LLVMValueRef Val,
 878--                                LLVMTypeRef DestTy, const char *Name);
 879	bit_cast (a_value: LLVM_VALUE; a_destination_type: LLVM_TYPE; a_name: ABSTRACT_STRING): LLVM_BITCAST_INST
 880		-- An instruction casting `a_value' into `a_destination_type'.
 881	require
 882		a_value/=Void
 883		a_destination_type/=Void
 884		a_name/=Void
 885	do
 886		create Result.from_external_pointer(llvmbuild_bit_cast(handle,a_value.handle,a_destination_type.handle,a_name.to_external))
 887	ensure Result/=Void
 888	end
 889
 890-- LLVMValueRef LLVMBuildZExtOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
 891--                                     LLVMTypeRef DestTy, const char *Name);
 892-- LLVMValueRef LLVMBuildSExtOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
 893--                                     LLVMTypeRef DestTy, const char *Name);
 894-- LLVMValueRef LLVMBuildTruncOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
 895--                                      LLVMTypeRef DestTy, const char *Name);
 896-- LLVMValueRef LLVMBuildPointerCast(LLVMBuilderRef, LLVMValueRef Val,
 897--                                   LLVMTypeRef DestTy, const char *Name);
 898-- LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef, LLVMValueRef Val,
 899--                               LLVMTypeRef DestTy, const char *Name);
 900-- LLVMValueRef LLVMBuildFPCast(LLVMBuilderRef, LLVMValueRef Val,
 901--                              LLVMTypeRef DestTy, const char *Name);
 902-- 
 903feature {ANY} -- Comparisons
 904	icmp (a_predicate: LLVMINT_PREDICATE_ENUM; a_left,a_right: LLVM_VALUE;a_name: ABSTRACT_STRING): LLVM_ICMP_INST
 905		-- An 'icmp' instruction that will return a boolean value or a vector of boolean values based on comparison of its two integer, integer vector, or pointer operands. `a_predicate' is the condition code indicating the kind of comparison to perform. In LLVM assembler it is not a value, but a keyword. The possible condition code are:
 906
 907		--   1. eq: equal
 908		--   2. ne: not equal
 909		--   3. ugt: unsigned greater than
 910		--   4. uge: unsigned greater or equal
 911		--   5. ult: unsigned less than
 912		--   6. ule: unsigned less or equal
 913		--   7. sgt: signed greater than
 914		--   8. sge: signed greater or equal
 915		--   9. slt: signed less than
 916		--  10. sle: signed less or equal
 917		
 918		--The remaining two arguments must be integer or pointer or integer vector typed. They must also be identical types.
 919		--Semantics:
 920		--
 921		--The 'icmp' compares op1 and op2 according to the condition code given as cond. The comparison performed always yields either an i1 or vector of i1 result, as follows:
 922		--
 923		--   1. eq: yields true if the operands are equal, false otherwise. No sign interpretation is necessary or performed.
 924		--   2. ne: yields true if the operands are unequal, false otherwise. No sign interpretation is necessary or performed.
 925		--   3. ugt: interprets the operands as unsigned values and yields true if op1 is greater than op2.
 926		--   4. uge: interprets the operands as unsigned values and yields true if op1 is greater than or equal to op2.
 927		--   5. ult: interprets the operands as unsigned values and yields true if op1 is less than op2.
 928		--   6. ule: interprets the operands as unsigned values and yields true if op1 is less than or equal to op2.
 929		--   7. sgt: interprets the operands as signed values and yields true if op1 is greater than op2.
 930		--   8. sge: interprets the operands as signed values and yields true if op1 is greater than or equal to op2.
 931		--   9. slt: interprets the operands as signed values and yields true if op1 is less than op2.
 932		--  10. sle: interprets the operands as signed values and yields true if op1 is less than or equal to op2.
 933		--
 934		--If the operands are pointer typed, the pointer values are compared as if they were integers.
 935		--
 936		--If the operands are integer vectors, then they are compared element by element. The result is an i1 vector with the same number of elements as the values being compared. Otherwise, the result is an i1.
 937		--
 938		require 
 939			a_left/=Void
 940			a_right=Void
 941			same_type: a_left.type ~ a_right.type 
 942			same_size_vectors: a_left.is_constant_vector implies a_left.as_constant_vector.type.size = a_right.as_constant_vector.type.size
 943		do
 944			create Result.from_external_pointer(llvmbuild_icmp(handle,a_predicate.value,
 945			a_left.handle,a_right.handle,a_name.to_external))
 946		ensure 
 947			Result/=Void
 948			-- TODO: result type is an i1 or a vector 
 949			-- TODO: a_left.is_constant_vector implies the-result-of-the-instruction.is_constant_vector and then a_left.as_constant_vector.type.size = Result.as
 950		end
 951
 952	fcmp (a_predicate: LLVMREAL_PREDICATE_ENUM; a_left, a_right: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_FCMP_INST
 953		-- Floating point comparison. 
 954
 955		-- TODO: adapt main LLVM documentation
 956	require
 957		a_left/=Void
 958		a_right/=Void
 959		a_name/=Void
 960		same_type: a_left.type ~ a_right.type
 961		-- TODO: provide remaining preconditions
 962	do
 963		create Result.from_external_pointer
 964		(llvmbuild_fcmp(handle, a_predicate.value, a_left.handle, a_right.handle, a_name.to_external))
 965	ensure 
 966		Result/=Void
 967	end
 968
 969feature {ANY} -- Miscellaneous instructions
 970
 971	-- LLVMValueRef LLVMBuildPhi(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
 972
 973	call (a_function: LLVM_FUNCTION; some_arguments: COLLECTION[LLVM_VALUE]; a_name: ABSTRACT_STRING): LLVM_CALL_INST
 974		-- A "call" instruction that will invoke `a_function' with `some_arguments'
 975
 976		-- TODO: adapt main LLVM doc
 977	require
 978		a_function/=Void
 979		some_arguments/=Void 
 980		-- TODO: allow some_arguments=Void for argument-less functions.
 981		a_name/=Void
 982	do
 983		create Result.from_external_pointer
 984		(llvmbuild_call(handle, a_function.handle, collection_to_c_array(some_arguments).storage.to_external,some_arguments.count.to_natural_32,a_name.to_external))
 985	ensure 
 986		Result/=Void
 987	end
 988
 989	select_inst (an_if, a_then, an_else: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_SELECT_INST
 990		-- A new 'select' instruction which choose one value based on a condition, without branching.
 991
 992		-- The 'select' instruction requires an 'i1' value or a vector of 'i1' values indicating the condition, and two values of the same first class type. If the val1/val2 are vectors and the condition is a scalar, then entire vectors are selected, not individual elements.
 993
 994		-- If the condition is an i1 and it evaluates to 1, the instruction returns the first value argument; otherwise, it returns the second value argument. If the condition is a vector of i2, then the value arguments must be vectors of the same size, and the selection is done element by element.
 995	require 
 996		an_if /= Void
 997		a_then /= Void
 998		an_else /= Void
 999		a_name /= Void
1000		an_if_is_boolean: {LLVM_INTEGER_TYPE} ?:= an_if.type
1001	do
1002		create Result.from_external_pointer(llvmbuild_select(handle,an_if.handle,a_then.handle,an_else.handle,a_name.to_external))
1003	ensure
1004		Result/=Void
1005	end
1006
1007	-- LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef, LLVMValueRef List, LLVMTypeRef Ty,
1008--                             const char *Name);
1009feature {ANY} -- Instructions on vectors
1010	extract_element(a_vector: LLVM_VALUE; an_index: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_EXTRACT_VALUE_INST
1011		-- An "extract_element" instruction that will extract the element of `a_vector' referred by `an_index'.
1012
1013		-- TODO: C API requires an_index to be a LLVMValueRef; currently Liberty wrappers do not distinguish them.
1014	require
1015		a_vector/=Void
1016		an_index/=Void
1017		a_name/=Void
1018	do
1019		create Result.from_external_pointer(llvmbuild_extract_element
1020		(handle,a_vector.handle,an_index.handle, a_name.to_external))
1021	ensure Result/=Void
1022	end
1023
1024	insert_element (a_vector: LLVM_VALUE; an_element: LLVM_VALUE; an_index: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_INSERT_ELEMENT_INST
1025		-- An "insertelement" instruction that will insert `an_element' into
1026		-- `a_vector' at `an_index'. The result of this instruction will be a
1027		-- vector of the same type as `a_vector'; its element values will be
1028		-- those of `a_vector' except at position `an_index', where it gets
1029		-- `an_element'. If `an_index' exceeds the length of `a_vector', the
1030		-- results are undefined (TODO: perhaps this shall be changed into a
1031		-- precondition).
1032
1033	require 
1034		a_vector/=Void
1035		an_element/=Void
1036		an_index/=Void
1037		a_vector.type.is_vector
1038		an_element_fits_into_a_vector: a_vector.type.as_vector.element_type.is_equal(an_element.type)
1039	do
1040		create Result.from_external_pointer(llvmbuild_insert_element
1041		(handle, a_vector.handle, an_element.handle, an_index.handle, a_name.to_external))
1042	ensure Result/=Void
1043	end
1044
1045	shuffle_vector (a_vector, another_vector: LLVM_VALUE; a_mask: LLVM_VALUE; a_name: ABSTRACT_STRING): LLVM_SHUFFLE_VECTOR_INST
1046		-- A "shufflevector" instruction that will construct a permutation of
1047		-- elements from `a_vector' and `another_vector', returning a vector
1048		-- with the same element type as the input and length that is the same
1049		-- as the shuffle mask.
1050		
1051		-- The third argument is a shuffle mask whose element type is always
1052		-- 'i32'. The result of the instruction is a vector whose length is the
1053		-- same as the shuffle mask and whose element type is the same as the
1054		-- element type of the first two operands.
1055		
1056		-- The shuffle mask operand is required to be a constant vector with
1057		-- either constant integer or undef values. (TODO: turn it into a precondition).
1058		
1059		-- The elements of the two input vectors are numbered from left to
1060		-- right across both of the vectors. The shuffle mask operand
1061		-- specifies, for each element of the result vector, which element of
1062		-- the two input vectors the result element gets. The element selector
1063		-- may be undef (meaning "don't care") and the second operand may be
1064		-- undef if performing a shuffle from only one vector.
1065	require
1066		a_vector/=Void
1067		another_vector/=Void
1068		a_mask/=Void
1069		a_name/=Void
1070		vectors_fits: a_vector.type ~ another_vector.type
1071		both_are_vectors: a_vector.type.is_vector and another_vector.type.is_vector
1072		same_element_type: a_vector.type.as_vector.element_type ~ another_vector.type.as_vector.element_type
1073		mask_is_a_vector_of_32bit_integers: a_mask.type.is_vector and then a_mask.type.as_vector.element_type.is_integer and then a_mask.type.as_vector.element_type.as_integer.width.to_integer_32 = 32
1074	do
1075		create Result.from_external_pointer(llvmbuild_shuffle_vector
1076		(handle, a_vector.handle,another_vector.handle, a_mask.handle, a_name.to_external))
1077	ensure Result/=Void
1078	end
1079
1080feature {ANY} -- Instructions on aggregates (structures or arrays)
1081	extract_value (an_aggregate: LLVM_VALUE; an_index: NATURAL_32; a_name: ABSTRACT_STRING): LLVM_EXTRACT_VALUE_INST
1082		-- An "extractvalue" instruction that will extract the value of a struct field or array element from `an_aggregate' value.
1083	require
1084		an_aggregate/=Void
1085		a_name/=Void
1086		an_aggregate.type.is_struct or an_aggregate.type.is_array
1087	do
1088		create Result.from_external_pointer(llvmbuild_extract_value
1089		(handle, an_aggregate.handle, an_index, a_name.to_external))
1090	ensure	 Result/=Void
1091	end
1092		
1093	insert_value (an_aggregate: LLVM_VALUE; an_element: LLVM_VALUE; an_index: NATURAL_32; a_name: ABSTRACT_STRING): LLVM_INSERT_VALUE_INST
1094		-- An "insertvalue" instruction that will insert `an_element' at
1095		-- `an_index' into a struct field or array element in `an_aggregate'.
1096
1097		-- The first operand of an 'insertvalue' instruction is a value of struct or array type. The second operand is a first-class value to insert. The following operands are constant indices indicating the position at which to insert the value in a similar manner as indices in a 'getelementptr' instruction. The value to insert must have the same type as the value identified by the indices.
1098
1099		-- The result is an aggregate of the same type as val. Its value is that of val except that the value at the position specified by the indices is that of elt.
1100	require 
1101		an_aggregate/=Void
1102		an_element/=Void
1103		a_name/=Void
1104		an_aggregate.type.is_struct or an_aggregate.type.is_array
1105		an_element_fits_at_an_index: an_element.type.is_equal(an_aggregate.type.as_struct.element(an_index.to_integer_32))
1106	do
1107		create Result.from_external_pointer(llvmbuild_insert_value
1108		(handle,an_aggregate.handle,an_element.handle,an_index,a_name.to_external))
1109	ensure Result/=Void
1110	end
1111
1112	-- LLVMValueRef LLVMBuildIsNull(LLVMBuilderRef, LLVMValueRef Val,
1113--                              const char *Name);
1114-- LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef, LLVMValueRef Val,
1115--                                 const char *Name);
1116-- LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef LHS,
1117--                               LLVMValueRef RHS, const char *Name);
1118-- 
1119-- 
1120feature {} 
1121	struct_size: like size_t
1122		do
1123			not_yet_implemented
1124		end
1125
1126	dispos…

Large files files are truncated, but you can click here to view the full file