fctiwz
Floating Convert to Integer Word with round toward Zero - FC 00 00 1E
fctiwz

Instruction Syntax

Mnemonic Format Flags
fctiwz frD,frB Rc = 0
fctiwz. frD,frB Rc = 1

Instruction Encoding

1
1
1
1
1
1
D
D
D
D
D
0
0
0
0
0
B
B
B
B
B
0
0
0
0
0
0
1
1
1
1
Rc

Field Bits Description
Primary Opcode 0-5 111111 (0x3F)
frD 6-10 Destination floating-point register
Reserved 11-15 00000
frB 16-20 Source floating-point register B
Reserved 21 0
XO 22-30 000001111 (15)
Rc 31 Record Condition Register

Operation

if frB is a NaN then
  frD ← 0x8000_0000_0000_0000
else
  temp ← ConvertToInteger32RoundToZero(frB)
  frD ← 0x0000_0000 || temp

The floating-point operand in register frB is converted to a 32-bit signed integer, using round-toward-zero mode (truncation), and placed in the low-order 32 bits of register frD. The high-order 32 bits of frD are cleared to zero.

Note: This instruction always rounds toward zero (truncates), regardless of the current FPSCR[RN] rounding mode setting. This provides a predictable truncation behavior commonly needed in C-style type conversions. If the operand is greater than 2³¹ - 1, the result saturates to 0x7FFFFFFF. If the operand is less than -2³¹, the result saturates to 0x80000000.

Affected Registers

Floating-Point Status and Control Register (FPSCR)

Affected fields:

For more information on floating-point status see Section 2.1.4, "Floating-Point Status and Control Register (FPSCR)," in the PowerPC Microprocessor Family: The Programming Environments manual.

Examples

C-Style Type Conversion (Truncation)

# Equivalent to C: int result = (int)float_value;
lfd f1, float_value(r0)     # Load floating-point value
fctiwz f2, f1               # Convert with truncation
stfd f2, temp_storage(r0)   # Store to memory
lwz r3, temp_storage+4(r0)  # Load integer result (truncated)
stw r3, int_result(r0)      # Store final result

Truncate Fractional Parts

# Remove fractional part from floating-point numbers
lfd f1, input_value(r0)     # Load value (e.g., 123.789)
fctiwz f2, f1               # Convert to integer (123)
stfd f2, temp_int(r0)       # Store temporarily
lwz r3, temp_int+4(r0)      # Load truncated integer
# Convert back to floating-point if needed
lis r4, 0x4330             # Load double bias
stw r4, temp_conv(r0)      # Store upper word
xoris r3, r3, 0x8000       # Flip sign bit for bias calculation
stw r3, temp_conv+4(r0)    # Store lower word
lfd f3, temp_conv(r0)      # Load as double
lfd f4, double_bias(r0)    # Load bias constant
fsub f5, f3, f4            # Subtract bias to get truncated value
stfd f5, truncated_result(r0) # Store truncated floating-point result

Fast Modulo Operation

# Calculate floating-point modulo using truncation
# result = a - (int)(a/b) * b
lfd f1, value_a(r0)        # Load dividend
lfd f2, value_b(r0)        # Load divisor
fdiv f3, f1, f2            # a / b
fctiwz f4, f3              # Truncate to integer
stfd f4, temp_int(r0)      # Store temporarily
lwz r3, temp_int+4(r0)     # Load integer quotient
# Convert integer back to floating-point
std r3, temp_conv(r0)      # Store as 64-bit integer
lfd f5, temp_conv(r0)      # Load as floating-point
fcfid f6, f5               # Convert integer to floating-point
fmul f7, f6, f2            # (int)(a/b) * b
fsub f8, f1, f7            # a - (int)(a/b) * b = modulo
stfd f8, modulo_result(r0) # Store modulo result

Digital Signal Processing

# Quantize floating-point samples to fixed-point
lfd f1, sample_value(r0)   # Load sample (-1.0 to 1.0)
lfd f2, quantize_scale(r0) # Load scale (e.g., 32767.0 for 16-bit)
fmul f3, f1, f2            # Scale sample
fctiwz f4, f3              # Truncate to integer (quantize)
stfd f4, temp_sample(r0)   # Store temporarily
lwz r3, temp_sample+4(r0)  # Load quantized sample
sth r3, output_sample(r0)  # Store as 16-bit sample

Graphics Texture Coordinate Calculation

# Convert normalized texture coordinates to pixel coordinates
lfd f1, tex_u(r0)          # Load U coordinate (0.0 to 1.0)
lfd f2, tex_v(r0)          # Load V coordinate (0.0 to 1.0)
lfd f3, texture_width(r0)  # Load texture width (e.g., 256.0)
lfd f4, texture_height(r0) # Load texture height (e.g., 256.0)
fmul f5, f1, f3            # U * width
fmul f6, f2, f4            # V * height
fctiwz f7, f5              # Truncate U to pixel coordinate
fctiwz f8, f6              # Truncate V to pixel coordinate
stfd f7, temp_u(r0)        # Store U temporarily
stfd f8, temp_v(r0)        # Store V temporarily
lwz r3, temp_u+4(r0)       # Load pixel U
lwz r4, temp_v+4(r0)       # Load pixel V
stw r3, pixel_u(r0)        # Store final pixel U
stw r4, pixel_v(r0)        # Store final pixel V

Game Engine Frame Rate Calculation

# Calculate integer frame rate from frame time
lfd f1, frame_time(r0)     # Load frame time in seconds
lfd f2, one_constant(r0)   # Load 1.0
fdiv f3, f2, f1            # Calculate FPS
fctiwz f4, f3              # Truncate to integer FPS
stfd f4, temp_fps(r0)      # Store temporarily
lwz r3, temp_fps+4(r0)     # Load integer FPS
stw r3, display_fps(r0)    # Store for display

Fixed-Point Arithmetic Conversion

# Convert floating-point to 16.16 fixed-point format
lfd f1, float_input(r0)    # Load floating-point value
lfd f2, fixed_scale(r0)    # Load 65536.0 (2^16)
fmul f3, f1, f2            # Scale to fixed-point range
fctiwz f4, f3              # Truncate to integer
stfd f4, temp_fixed(r0)    # Store temporarily
lwz r3, temp_fixed+4(r0)   # Load fixed-point value
stw r3, fixed_result(r0)   # Store 16.16 fixed-point result

Hash Table Index Calculation

# Calculate hash table index from floating-point key
lfd f1, hash_key(r0)       # Load floating-point hash key
lfd f2, hash_multiplier(r0) # Load hash multiplier
lfd f3, table_size(r0)     # Load hash table size
fmul f4, f1, f2            # Apply hash function
fctiwz f5, f4              # Truncate fractional part
stfd f5, temp_hash(r0)     # Store temporarily
lwz r3, temp_hash+4(r0)    # Load hash value
lwz r4, table_size_int(r0) # Load table size as integer
divw r5, r3, r4            # Divide by table size
mullw r5, r5, r4           # Multiply back
subf r3, r5, r3            # Calculate modulo (remainder)
stw r3, hash_index(r0)     # Store final hash index

Probability Distribution Sampling

# Convert random float to discrete probability index
lfd f1, random_value(r0)   # Load random value (0.0 to 1.0)
lfd f2, num_outcomes(r0)   # Load number of outcomes
fmul f3, f1, f2            # Scale to range [0, num_outcomes)
fctiwz f4, f3              # Truncate to get index
stfd f4, temp_index(r0)    # Store temporarily
lwz r3, temp_index+4(r0)   # Load discrete index
stw r3, outcome_index(r0)  # Store outcome index

Performance-Critical Loop Bounds

# Calculate loop iteration count with truncation
lfd f1, work_units(r0)     # Load total work units
lfd f2, chunk_size(r0)     # Load work per iteration
fdiv f3, f1, f2            # Calculate iterations needed
fctiwz f4, f3              # Truncate to integer iterations
stfd f4, temp_iters(r0)    # Store temporarily
lwz r3, temp_iters+4(r0)   # Load iteration count
mtctr r3                   # Set up loop counter
processing_loop:
    # Process one chunk of work
    bdnz processing_loop   # Loop until done

Related Instructions

fctiw, fcfid, frsp, stfd, lfd

Back to Index