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:

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

Related Instructions

fctiwz, frsp, stfd, lfd, fcmpo

Back to Index