Instruction Syntax
Mnemonic | Format | Flags |
fctiwz | frD,frB | Rc = 0 |
fctiwz. | frD,frB | Rc = 1 |
Instruction Encoding
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:
- FPRF (Floating-Point Result Flags) - if Rc = 1
- FX (Floating-Point Exception Summary)
- XX (Inexact Exception) - if truncation occurred
- VXCVI (Invalid Operation Exception for invalid integer conversion)
- FR (Fraction Rounded)
- FI (Fraction Inexact)
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