fctiw
Floating Convert to Integer Word - FC 00 00 1C
fctiw
Instruction Syntax
Mnemonic | Format | Flags |
fctiw | frD,frB | Rc = 0 |
fctiw. | 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
0
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 | 000001110 (14) |
Rc | 31 | Record Condition Register |
Operation
if frB is a NaN then frD ← 0x8000_0000_0000_0000 else temp ← ConvertToInteger32(frB) frD ← 0x0000_0000 || temp
The floating-point operand in register frB is converted to a 32-bit signed integer, using the rounding mode specified by FPSCR[RN], and placed in the low-order 32 bits of register frD. The high-order 32 bits of frD are cleared to zero.
Note: 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. If the operand is a NaN, the result is 0x80000000. The conversion follows IEEE-754 standard behavior.
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 rounding 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
Basic Floating-Point to Integer Conversion
lfd f1, float_value(r0) # Load floating-point value fctiw f2, f1 # Convert to integer (stored in FPR) stfd f2, temp_storage(r0) # Store to memory lwz r3, temp_storage+4(r0) # Load lower 32 bits (the integer) stw r3, int_result(r0) # Store integer result
Convert Array of Floats to Integers
# Convert floating-point array to integer array li r4, 0 # Initialize index li r5, 100 # Array size mtctr r5 # Set up loop counter convert_loop: lfdx f1, r3, r4 # Load float_array[i] fctiw f2, f1 # Convert to integer stfd f2, temp_storage(r0) # Store to temporary location lwz r6, temp_storage+4(r0) # Extract integer from low 32 bits stwx r6, r7, r4 # Store to int_array[i] addi r4, r4, 8 # Increment index (8 bytes for double) bdnz convert_loop # Loop until done
Safe Conversion with Range Checking
# Convert float to int with overflow detection lfd f1, input_value(r0) # Load input value lfd f2, max_int(r0) # Load 2147483647.0 (INT_MAX) lfd f3, min_int(r0) # Load -2147483648.0 (INT_MIN) fcmpo cr0, f1, f2 # Compare with maximum bgt overflow_max # Branch if value > INT_MAX fcmpo cr0, f1, f3 # Compare with minimum blt overflow_min # Branch if value < INT_MIN # Value is within range, convert normally fctiw f4, f1 # Convert to integer stfd f4, temp_storage(r0) # Store to memory lwz r3, temp_storage+4(r0) # Load integer result b conversion_done overflow_max: li r3, 0x7FFFFFFF # Set to INT_MAX b conversion_done overflow_min: lis r3, 0x8000 # Set to INT_MIN (0x80000000) conversion_done: stw r3, result(r0) # Store final result
Physics Engine Coordinate Conversion
# Convert world coordinates to screen pixels lfd f1, world_x(r0) # Load world X coordinate lfd f2, world_y(r0) # Load world Y coordinate lfd f3, scale_factor(r0) # Load scaling factor fmul f1, f1, f3 # Scale X coordinate fmul f2, f2, f3 # Scale Y coordinate fctiw f4, f1 # Convert X to integer pixel fctiw f5, f2 # Convert Y to integer pixel stfd f4, temp_x(r0) # Store X temporarily stfd f5, temp_y(r0) # Store Y temporarily lwz r3, temp_x+4(r0) # Load pixel X lwz r4, temp_y+4(r0) # Load pixel Y stw r3, pixel_x(r0) # Store final pixel X stw r4, pixel_y(r0) # Store final pixel Y
Audio Sample Processing
# Convert normalized audio samples to 16-bit integers lfd f1, audio_sample(r0) # Load normalized sample (-1.0 to 1.0) lfd f2, scale_16bit(r0) # Load 32767.0 (max 16-bit value) fmul f3, f1, f2 # Scale to 16-bit range fctiw f4, f3 # Convert to integer stfd f4, temp_sample(r0) # Store temporarily lwz r3, temp_sample+4(r0) # Load integer sample # Clamp to 16-bit range if needed cmpwi cr0, r3, 32767 # Compare with max ble check_min # Branch if <= max li r3, 32767 # Clamp to maximum b store_sample check_min: cmpwi cr0, r3, -32768 # Compare with min bge store_sample # Branch if >= min li r3, -32768 # Clamp to minimum store_sample: sth r3, output_sample(r0) # Store 16-bit sample
Game Score Calculation
# Convert floating-point game score to integer display lfd f1, game_score(r0) # Load floating-point score fctiw f2, f1 # Convert to integer stfd f2, temp_score(r0) # Store temporarily lwz r3, temp_score+4(r0) # Load integer score stw r3, display_score(r0) # Store for display
Financial Calculation
# Convert currency amount to cents (integer) lfd f1, dollar_amount(r0) # Load dollar amount (e.g., 123.45) lfd f2, cents_multiplier(r0) # Load 100.0 fmul f3, f1, f2 # Convert to cents (12345.0) fctiw f4, f3 # Convert to integer stfd f4, temp_cents(r0) # Store temporarily lwz r3, temp_cents+4(r0) # Load integer cents stw r3, cents_amount(r0) # Store cents amount
Color Channel Conversion
# Convert normalized color values to 8-bit integers lfd f1, red_normalized(r0) # Load red (0.0 to 1.0) lfd f2, green_normalized(r0) # Load green (0.0 to 1.0) lfd f3, blue_normalized(r0) # Load blue (0.0 to 1.0) lfd f4, color_scale(r0) # Load 255.0 fmul f1, f1, f4 # Scale red to 0-255 fmul f2, f2, f4 # Scale green to 0-255 fmul f3, f3, f4 # Scale blue to 0-255 fctiw f5, f1 # Convert red to integer fctiw f6, f2 # Convert green to integer fctiw f7, f3 # Convert blue to integer stfd f5, temp_red(r0) # Store red temporarily stfd f6, temp_green(r0) # Store green temporarily stfd f7, temp_blue(r0) # Store blue temporarily lbz r3, temp_red+7(r0) # Load red byte lbz r4, temp_green+7(r0) # Load green byte lbz r5, temp_blue+7(r0) # Load blue byte stb r3, final_red(r0) # Store final red stb r4, final_green(r0) # Store final green stb r5, final_blue(r0) # Store final blue
Mathematical Function Implementation
# Implement floor() function using fctiw lfd f1, input_value(r0) # Load input value fcmpo cr0, f1, f0 # Compare with zero bge positive_value # Branch if positive # Negative value - need special handling for floor lfd f2, neg_one(r0) # Load -1.0 fadd f3, f1, f2 # Subtract 1 from negative value fctiw f4, f3 # Convert to integer b conversion_done positive_value: fctiw f4, f1 # Convert positive value directly conversion_done: stfd f4, temp_floor(r0) # Store temporarily lwz r3, temp_floor+4(r0) # Load floor result stw r3, floor_result(r0) # Store final floor value
Loop Index Conversion
# Convert floating-point loop bound to integer lfd f1, loop_bound(r0) # Load floating-point bound fctiw f2, f1 # Convert to integer stfd f2, temp_bound(r0) # Store temporarily lwz r3, temp_bound+4(r0) # Load integer bound mtctr r3 # Set up loop counter processing_loop: # Loop body here bdnz processing_loop # Loop until counter reaches zero