162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci    NetWinder Floating Point Emulator
462306a36Sopenharmony_ci    (c) Rebel.COM, 1998,1999
562306a36Sopenharmony_ci    (c) Philip Blundell, 2001
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci*/
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifndef __FPOPCODE_H__
1262306a36Sopenharmony_ci#define __FPOPCODE_H__
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/*
1662306a36Sopenharmony_ciARM Floating Point Instruction Classes
1762306a36Sopenharmony_ci| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
1862306a36Sopenharmony_ci|c o n d|1 1 0 P|U|u|W|L|   Rn  |v|  Fd |0|0|0|1|  o f f s e t  | CPDT
1962306a36Sopenharmony_ci|c o n d|1 1 0 P|U|w|W|L|   Rn  |x|  Fd |0|0|1|0|  o f f s e t  | CPDT (copro 2)
2062306a36Sopenharmony_ci| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
2162306a36Sopenharmony_ci|c o n d|1 1 1 0|a|b|c|d|e|  Fn |j|  Fd |0|0|0|1|f|g|h|0|i|  Fm | CPDO
2262306a36Sopenharmony_ci|c o n d|1 1 1 0|a|b|c|L|e|  Fn |   Rd  |0|0|0|1|f|g|h|1|i|  Fm | CPRT
2362306a36Sopenharmony_ci|c o n d|1 1 1 0|a|b|c|1|e|  Fn |1|1|1|1|0|0|0|1|f|g|h|1|i|  Fm | comparisons
2462306a36Sopenharmony_ci| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ciCPDT		data transfer instructions
2762306a36Sopenharmony_ci		LDF, STF, LFM (copro 2), SFM (copro 2)
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ciCPDO		dyadic arithmetic instructions
3062306a36Sopenharmony_ci		ADF, MUF, SUF, RSF, DVF, RDF,
3162306a36Sopenharmony_ci		POW, RPW, RMF, FML, FDV, FRD, POL
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ciCPDO		monadic arithmetic instructions
3462306a36Sopenharmony_ci		MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP,
3562306a36Sopenharmony_ci		SIN, COS, TAN, ASN, ACS, ATN, URD, NRM
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ciCPRT		joint arithmetic/data transfer instructions
3862306a36Sopenharmony_ci		FIX (arithmetic followed by load/store)
3962306a36Sopenharmony_ci		FLT (load/store followed by arithmetic)
4062306a36Sopenharmony_ci		CMF, CNF CMFE, CNFE (comparisons)
4162306a36Sopenharmony_ci		WFS, RFS (write/read floating point status register)
4262306a36Sopenharmony_ci		WFC, RFC (write/read floating point control register)
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cicond		condition codes
4562306a36Sopenharmony_ciP		pre/post index bit: 0 = postindex, 1 = preindex
4662306a36Sopenharmony_ciU		up/down bit: 0 = stack grows down, 1 = stack grows up
4762306a36Sopenharmony_ciW		write back bit: 1 = update base register (Rn)
4862306a36Sopenharmony_ciL		load/store bit: 0 = store, 1 = load
4962306a36Sopenharmony_ciRn		base register
5062306a36Sopenharmony_ciRd		destination/source register
5162306a36Sopenharmony_ciFd		floating point destination register
5262306a36Sopenharmony_ciFn		floating point source register
5362306a36Sopenharmony_ciFm		floating point source register or floating point constant
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ciuv		transfer length (TABLE 1)
5662306a36Sopenharmony_ciwx		register count (TABLE 2)
5762306a36Sopenharmony_ciabcd		arithmetic opcode (TABLES 3 & 4)
5862306a36Sopenharmony_cief		destination size (rounding precision) (TABLE 5)
5962306a36Sopenharmony_cigh		rounding mode (TABLE 6)
6062306a36Sopenharmony_cij		dyadic/monadic bit: 0 = dyadic, 1 = monadic
6162306a36Sopenharmony_cii 		constant bit: 1 = constant (TABLE 6)
6262306a36Sopenharmony_ci*/
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci/*
6562306a36Sopenharmony_ciTABLE 1
6662306a36Sopenharmony_ci+-------------------------+---+---+---------+---------+
6762306a36Sopenharmony_ci|  Precision              | u | v | FPSR.EP | length  |
6862306a36Sopenharmony_ci+-------------------------+---+---+---------+---------+
6962306a36Sopenharmony_ci| Single                  | 0 | 0 |    x    | 1 words |
7062306a36Sopenharmony_ci| Double                  | 1 | 1 |    x    | 2 words |
7162306a36Sopenharmony_ci| Extended                | 1 | 1 |    x    | 3 words |
7262306a36Sopenharmony_ci| Packed decimal          | 1 | 1 |    0    | 3 words |
7362306a36Sopenharmony_ci| Expanded packed decimal | 1 | 1 |    1    | 4 words |
7462306a36Sopenharmony_ci+-------------------------+---+---+---------+---------+
7562306a36Sopenharmony_ciNote: x = don't care
7662306a36Sopenharmony_ci*/
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/*
7962306a36Sopenharmony_ciTABLE 2
8062306a36Sopenharmony_ci+---+---+---------------------------------+
8162306a36Sopenharmony_ci| w | x | Number of registers to transfer |
8262306a36Sopenharmony_ci+---+---+---------------------------------+
8362306a36Sopenharmony_ci| 0 | 1 |  1                              |
8462306a36Sopenharmony_ci| 1 | 0 |  2                              |
8562306a36Sopenharmony_ci| 1 | 1 |  3                              |
8662306a36Sopenharmony_ci| 0 | 0 |  4                              |
8762306a36Sopenharmony_ci+---+---+---------------------------------+
8862306a36Sopenharmony_ci*/
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci/*
9162306a36Sopenharmony_ciTABLE 3: Dyadic Floating Point Opcodes
9262306a36Sopenharmony_ci+---+---+---+---+----------+-----------------------+-----------------------+
9362306a36Sopenharmony_ci| a | b | c | d | Mnemonic | Description           | Operation             |
9462306a36Sopenharmony_ci+---+---+---+---+----------+-----------------------+-----------------------+
9562306a36Sopenharmony_ci| 0 | 0 | 0 | 0 | ADF      | Add                   | Fd := Fn + Fm         |
9662306a36Sopenharmony_ci| 0 | 0 | 0 | 1 | MUF      | Multiply              | Fd := Fn * Fm         |
9762306a36Sopenharmony_ci| 0 | 0 | 1 | 0 | SUF      | Subtract              | Fd := Fn - Fm         |
9862306a36Sopenharmony_ci| 0 | 0 | 1 | 1 | RSF      | Reverse subtract      | Fd := Fm - Fn         |
9962306a36Sopenharmony_ci| 0 | 1 | 0 | 0 | DVF      | Divide                | Fd := Fn / Fm         |
10062306a36Sopenharmony_ci| 0 | 1 | 0 | 1 | RDF      | Reverse divide        | Fd := Fm / Fn         |
10162306a36Sopenharmony_ci| 0 | 1 | 1 | 0 | POW      | Power                 | Fd := Fn ^ Fm         |
10262306a36Sopenharmony_ci| 0 | 1 | 1 | 1 | RPW      | Reverse power         | Fd := Fm ^ Fn         |
10362306a36Sopenharmony_ci| 1 | 0 | 0 | 0 | RMF      | Remainder             | Fd := IEEE rem(Fn/Fm) |
10462306a36Sopenharmony_ci| 1 | 0 | 0 | 1 | FML      | Fast Multiply         | Fd := Fn * Fm         |
10562306a36Sopenharmony_ci| 1 | 0 | 1 | 0 | FDV      | Fast Divide           | Fd := Fn / Fm         |
10662306a36Sopenharmony_ci| 1 | 0 | 1 | 1 | FRD      | Fast reverse divide   | Fd := Fm / Fn         |
10762306a36Sopenharmony_ci| 1 | 1 | 0 | 0 | POL      | Polar angle (ArcTan2) | Fd := arctan2(Fn,Fm)  |
10862306a36Sopenharmony_ci| 1 | 1 | 0 | 1 |          | undefined instruction | trap                  |
10962306a36Sopenharmony_ci| 1 | 1 | 1 | 0 |          | undefined instruction | trap                  |
11062306a36Sopenharmony_ci| 1 | 1 | 1 | 1 |          | undefined instruction | trap                  |
11162306a36Sopenharmony_ci+---+---+---+---+----------+-----------------------+-----------------------+
11262306a36Sopenharmony_ciNote: POW, RPW, POL are deprecated, and are available for backwards
11362306a36Sopenharmony_ci      compatibility only.
11462306a36Sopenharmony_ci*/
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci/*
11762306a36Sopenharmony_ciTABLE 4: Monadic Floating Point Opcodes
11862306a36Sopenharmony_ci+---+---+---+---+----------+-----------------------+-----------------------+
11962306a36Sopenharmony_ci| a | b | c | d | Mnemonic | Description           | Operation             |
12062306a36Sopenharmony_ci+---+---+---+---+----------+-----------------------+-----------------------+
12162306a36Sopenharmony_ci| 0 | 0 | 0 | 0 | MVF      | Move                  | Fd := Fm              |
12262306a36Sopenharmony_ci| 0 | 0 | 0 | 1 | MNF      | Move negated          | Fd := - Fm            |
12362306a36Sopenharmony_ci| 0 | 0 | 1 | 0 | ABS      | Absolute value        | Fd := abs(Fm)         |
12462306a36Sopenharmony_ci| 0 | 0 | 1 | 1 | RND      | Round to integer      | Fd := int(Fm)         |
12562306a36Sopenharmony_ci| 0 | 1 | 0 | 0 | SQT      | Square root           | Fd := sqrt(Fm)        |
12662306a36Sopenharmony_ci| 0 | 1 | 0 | 1 | LOG      | Log base 10           | Fd := log10(Fm)       |
12762306a36Sopenharmony_ci| 0 | 1 | 1 | 0 | LGN      | Log base e            | Fd := ln(Fm)          |
12862306a36Sopenharmony_ci| 0 | 1 | 1 | 1 | EXP      | Exponent              | Fd := e ^ Fm          |
12962306a36Sopenharmony_ci| 1 | 0 | 0 | 0 | SIN      | Sine                  | Fd := sin(Fm)         |
13062306a36Sopenharmony_ci| 1 | 0 | 0 | 1 | COS      | Cosine                | Fd := cos(Fm)         |
13162306a36Sopenharmony_ci| 1 | 0 | 1 | 0 | TAN      | Tangent               | Fd := tan(Fm)         |
13262306a36Sopenharmony_ci| 1 | 0 | 1 | 1 | ASN      | Arc Sine              | Fd := arcsin(Fm)      |
13362306a36Sopenharmony_ci| 1 | 1 | 0 | 0 | ACS      | Arc Cosine            | Fd := arccos(Fm)      |
13462306a36Sopenharmony_ci| 1 | 1 | 0 | 1 | ATN      | Arc Tangent           | Fd := arctan(Fm)      |
13562306a36Sopenharmony_ci| 1 | 1 | 1 | 0 | URD      | Unnormalized round    | Fd := int(Fm)         |
13662306a36Sopenharmony_ci| 1 | 1 | 1 | 1 | NRM      | Normalize             | Fd := norm(Fm)        |
13762306a36Sopenharmony_ci+---+---+---+---+----------+-----------------------+-----------------------+
13862306a36Sopenharmony_ciNote: LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN are deprecated, and are
13962306a36Sopenharmony_ci      available for backwards compatibility only.
14062306a36Sopenharmony_ci*/
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci/*
14362306a36Sopenharmony_ciTABLE 5
14462306a36Sopenharmony_ci+-------------------------+---+---+
14562306a36Sopenharmony_ci|  Rounding Precision     | e | f |
14662306a36Sopenharmony_ci+-------------------------+---+---+
14762306a36Sopenharmony_ci| IEEE Single precision   | 0 | 0 |
14862306a36Sopenharmony_ci| IEEE Double precision   | 0 | 1 |
14962306a36Sopenharmony_ci| IEEE Extended precision | 1 | 0 |
15062306a36Sopenharmony_ci| undefined (trap)        | 1 | 1 |
15162306a36Sopenharmony_ci+-------------------------+---+---+
15262306a36Sopenharmony_ci*/
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci/*
15562306a36Sopenharmony_ciTABLE 5
15662306a36Sopenharmony_ci+---------------------------------+---+---+
15762306a36Sopenharmony_ci|  Rounding Mode                  | g | h |
15862306a36Sopenharmony_ci+---------------------------------+---+---+
15962306a36Sopenharmony_ci| Round to nearest (default)      | 0 | 0 |
16062306a36Sopenharmony_ci| Round toward plus infinity      | 0 | 1 |
16162306a36Sopenharmony_ci| Round toward negative infinity  | 1 | 0 |
16262306a36Sopenharmony_ci| Round toward zero               | 1 | 1 |
16362306a36Sopenharmony_ci+---------------------------------+---+---+
16462306a36Sopenharmony_ci*/
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci/*
16762306a36Sopenharmony_ci===
16862306a36Sopenharmony_ci=== Definitions for load and store instructions
16962306a36Sopenharmony_ci===
17062306a36Sopenharmony_ci*/
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci/* bit masks */
17362306a36Sopenharmony_ci#define BIT_PREINDEX	0x01000000
17462306a36Sopenharmony_ci#define BIT_UP		0x00800000
17562306a36Sopenharmony_ci#define BIT_WRITE_BACK	0x00200000
17662306a36Sopenharmony_ci#define BIT_LOAD	0x00100000
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci/* masks for load/store */
17962306a36Sopenharmony_ci#define MASK_CPDT		0x0c000000	/* data processing opcode */
18062306a36Sopenharmony_ci#define MASK_OFFSET		0x000000ff
18162306a36Sopenharmony_ci#define MASK_TRANSFER_LENGTH	0x00408000
18262306a36Sopenharmony_ci#define MASK_REGISTER_COUNT	MASK_TRANSFER_LENGTH
18362306a36Sopenharmony_ci#define MASK_COPROCESSOR	0x00000f00
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci/* Tests for transfer length */
18662306a36Sopenharmony_ci#define TRANSFER_SINGLE		0x00000000
18762306a36Sopenharmony_ci#define TRANSFER_DOUBLE		0x00008000
18862306a36Sopenharmony_ci#define TRANSFER_EXTENDED	0x00400000
18962306a36Sopenharmony_ci#define TRANSFER_PACKED		MASK_TRANSFER_LENGTH
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci/* Get the coprocessor number from the opcode. */
19262306a36Sopenharmony_ci#define getCoprocessorNumber(opcode)	((opcode & MASK_COPROCESSOR) >> 8)
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci/* Get the offset from the opcode. */
19562306a36Sopenharmony_ci#define getOffset(opcode)		(opcode & MASK_OFFSET)
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci/* Tests for specific data transfer load/store opcodes. */
19862306a36Sopenharmony_ci#define TEST_OPCODE(opcode,mask)	(((opcode) & (mask)) == (mask))
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci#define LOAD_OP(opcode)   TEST_OPCODE((opcode),MASK_CPDT | BIT_LOAD)
20162306a36Sopenharmony_ci#define STORE_OP(opcode)  ((opcode & (MASK_CPDT | BIT_LOAD)) == MASK_CPDT)
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci#define LDF_OP(opcode)	(LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 1))
20462306a36Sopenharmony_ci#define LFM_OP(opcode)	(LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 2))
20562306a36Sopenharmony_ci#define STF_OP(opcode)	(STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 1))
20662306a36Sopenharmony_ci#define SFM_OP(opcode)	(STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 2))
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci#define PREINDEXED(opcode)		((opcode & BIT_PREINDEX) != 0)
20962306a36Sopenharmony_ci#define POSTINDEXED(opcode)		((opcode & BIT_PREINDEX) == 0)
21062306a36Sopenharmony_ci#define BIT_UP_SET(opcode)		((opcode & BIT_UP) != 0)
21162306a36Sopenharmony_ci#define BIT_UP_CLEAR(opcode)		((opcode & BIT_DOWN) == 0)
21262306a36Sopenharmony_ci#define WRITE_BACK(opcode)		((opcode & BIT_WRITE_BACK) != 0)
21362306a36Sopenharmony_ci#define LOAD(opcode)			((opcode & BIT_LOAD) != 0)
21462306a36Sopenharmony_ci#define STORE(opcode)			((opcode & BIT_LOAD) == 0)
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci/*
21762306a36Sopenharmony_ci===
21862306a36Sopenharmony_ci=== Definitions for arithmetic instructions
21962306a36Sopenharmony_ci===
22062306a36Sopenharmony_ci*/
22162306a36Sopenharmony_ci/* bit masks */
22262306a36Sopenharmony_ci#define BIT_MONADIC	0x00008000
22362306a36Sopenharmony_ci#define BIT_CONSTANT	0x00000008
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci#define CONSTANT_FM(opcode)		((opcode & BIT_CONSTANT) != 0)
22662306a36Sopenharmony_ci#define MONADIC_INSTRUCTION(opcode)	((opcode & BIT_MONADIC) != 0)
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci/* instruction identification masks */
22962306a36Sopenharmony_ci#define MASK_CPDO		0x0e000000	/* arithmetic opcode */
23062306a36Sopenharmony_ci#define MASK_ARITHMETIC_OPCODE	0x00f08000
23162306a36Sopenharmony_ci#define MASK_DESTINATION_SIZE	0x00080080
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci/* dyadic arithmetic opcodes. */
23462306a36Sopenharmony_ci#define ADF_CODE	0x00000000
23562306a36Sopenharmony_ci#define MUF_CODE	0x00100000
23662306a36Sopenharmony_ci#define SUF_CODE	0x00200000
23762306a36Sopenharmony_ci#define RSF_CODE	0x00300000
23862306a36Sopenharmony_ci#define DVF_CODE	0x00400000
23962306a36Sopenharmony_ci#define RDF_CODE	0x00500000
24062306a36Sopenharmony_ci#define POW_CODE	0x00600000
24162306a36Sopenharmony_ci#define RPW_CODE	0x00700000
24262306a36Sopenharmony_ci#define RMF_CODE	0x00800000
24362306a36Sopenharmony_ci#define FML_CODE	0x00900000
24462306a36Sopenharmony_ci#define FDV_CODE	0x00a00000
24562306a36Sopenharmony_ci#define FRD_CODE	0x00b00000
24662306a36Sopenharmony_ci#define POL_CODE	0x00c00000
24762306a36Sopenharmony_ci/* 0x00d00000 is an invalid dyadic arithmetic opcode */
24862306a36Sopenharmony_ci/* 0x00e00000 is an invalid dyadic arithmetic opcode */
24962306a36Sopenharmony_ci/* 0x00f00000 is an invalid dyadic arithmetic opcode */
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci/* monadic arithmetic opcodes. */
25262306a36Sopenharmony_ci#define MVF_CODE	0x00008000
25362306a36Sopenharmony_ci#define MNF_CODE	0x00108000
25462306a36Sopenharmony_ci#define ABS_CODE	0x00208000
25562306a36Sopenharmony_ci#define RND_CODE	0x00308000
25662306a36Sopenharmony_ci#define SQT_CODE	0x00408000
25762306a36Sopenharmony_ci#define LOG_CODE	0x00508000
25862306a36Sopenharmony_ci#define LGN_CODE	0x00608000
25962306a36Sopenharmony_ci#define EXP_CODE	0x00708000
26062306a36Sopenharmony_ci#define SIN_CODE	0x00808000
26162306a36Sopenharmony_ci#define COS_CODE	0x00908000
26262306a36Sopenharmony_ci#define TAN_CODE	0x00a08000
26362306a36Sopenharmony_ci#define ASN_CODE	0x00b08000
26462306a36Sopenharmony_ci#define ACS_CODE	0x00c08000
26562306a36Sopenharmony_ci#define ATN_CODE	0x00d08000
26662306a36Sopenharmony_ci#define URD_CODE	0x00e08000
26762306a36Sopenharmony_ci#define NRM_CODE	0x00f08000
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci/*
27062306a36Sopenharmony_ci===
27162306a36Sopenharmony_ci=== Definitions for register transfer and comparison instructions
27262306a36Sopenharmony_ci===
27362306a36Sopenharmony_ci*/
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci#define MASK_CPRT		0x0e000010	/* register transfer opcode */
27662306a36Sopenharmony_ci#define MASK_CPRT_CODE		0x00f00000
27762306a36Sopenharmony_ci#define FLT_CODE		0x00000000
27862306a36Sopenharmony_ci#define FIX_CODE		0x00100000
27962306a36Sopenharmony_ci#define WFS_CODE		0x00200000
28062306a36Sopenharmony_ci#define RFS_CODE		0x00300000
28162306a36Sopenharmony_ci#define WFC_CODE		0x00400000
28262306a36Sopenharmony_ci#define RFC_CODE		0x00500000
28362306a36Sopenharmony_ci#define CMF_CODE		0x00900000
28462306a36Sopenharmony_ci#define CNF_CODE		0x00b00000
28562306a36Sopenharmony_ci#define CMFE_CODE		0x00d00000
28662306a36Sopenharmony_ci#define CNFE_CODE		0x00f00000
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci/*
28962306a36Sopenharmony_ci===
29062306a36Sopenharmony_ci=== Common definitions
29162306a36Sopenharmony_ci===
29262306a36Sopenharmony_ci*/
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci/* register masks */
29562306a36Sopenharmony_ci#define MASK_Rd		0x0000f000
29662306a36Sopenharmony_ci#define MASK_Rn		0x000f0000
29762306a36Sopenharmony_ci#define MASK_Fd		0x00007000
29862306a36Sopenharmony_ci#define MASK_Fm		0x00000007
29962306a36Sopenharmony_ci#define MASK_Fn		0x00070000
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci/* condition code masks */
30262306a36Sopenharmony_ci#define CC_MASK		0xf0000000
30362306a36Sopenharmony_ci#define CC_NEGATIVE	0x80000000
30462306a36Sopenharmony_ci#define CC_ZERO		0x40000000
30562306a36Sopenharmony_ci#define CC_CARRY	0x20000000
30662306a36Sopenharmony_ci#define CC_OVERFLOW	0x10000000
30762306a36Sopenharmony_ci#define CC_EQ		0x00000000
30862306a36Sopenharmony_ci#define CC_NE		0x10000000
30962306a36Sopenharmony_ci#define CC_CS		0x20000000
31062306a36Sopenharmony_ci#define CC_HS		CC_CS
31162306a36Sopenharmony_ci#define CC_CC		0x30000000
31262306a36Sopenharmony_ci#define CC_LO		CC_CC
31362306a36Sopenharmony_ci#define CC_MI		0x40000000
31462306a36Sopenharmony_ci#define CC_PL		0x50000000
31562306a36Sopenharmony_ci#define CC_VS		0x60000000
31662306a36Sopenharmony_ci#define CC_VC		0x70000000
31762306a36Sopenharmony_ci#define CC_HI		0x80000000
31862306a36Sopenharmony_ci#define CC_LS		0x90000000
31962306a36Sopenharmony_ci#define CC_GE		0xa0000000
32062306a36Sopenharmony_ci#define CC_LT		0xb0000000
32162306a36Sopenharmony_ci#define CC_GT		0xc0000000
32262306a36Sopenharmony_ci#define CC_LE		0xd0000000
32362306a36Sopenharmony_ci#define CC_AL		0xe0000000
32462306a36Sopenharmony_ci#define CC_NV		0xf0000000
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci/* rounding masks/values */
32762306a36Sopenharmony_ci#define MASK_ROUNDING_MODE	0x00000060
32862306a36Sopenharmony_ci#define ROUND_TO_NEAREST	0x00000000
32962306a36Sopenharmony_ci#define ROUND_TO_PLUS_INFINITY	0x00000020
33062306a36Sopenharmony_ci#define ROUND_TO_MINUS_INFINITY	0x00000040
33162306a36Sopenharmony_ci#define ROUND_TO_ZERO		0x00000060
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci#define MASK_ROUNDING_PRECISION	0x00080080
33462306a36Sopenharmony_ci#define ROUND_SINGLE		0x00000000
33562306a36Sopenharmony_ci#define ROUND_DOUBLE		0x00000080
33662306a36Sopenharmony_ci#define ROUND_EXTENDED		0x00080000
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci/* Get the condition code from the opcode. */
33962306a36Sopenharmony_ci#define getCondition(opcode)		(opcode >> 28)
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci/* Get the source register from the opcode. */
34262306a36Sopenharmony_ci#define getRn(opcode)			((opcode & MASK_Rn) >> 16)
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci/* Get the destination floating point register from the opcode. */
34562306a36Sopenharmony_ci#define getFd(opcode)			((opcode & MASK_Fd) >> 12)
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci/* Get the first source floating point register from the opcode. */
34862306a36Sopenharmony_ci#define getFn(opcode)		((opcode & MASK_Fn) >> 16)
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci/* Get the second source floating point register from the opcode. */
35162306a36Sopenharmony_ci#define getFm(opcode)		(opcode & MASK_Fm)
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci/* Get the destination register from the opcode. */
35462306a36Sopenharmony_ci#define getRd(opcode)		((opcode & MASK_Rd) >> 12)
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci/* Get the rounding mode from the opcode. */
35762306a36Sopenharmony_ci#define getRoundingMode(opcode)		((opcode & MASK_ROUNDING_MODE) >> 5)
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci#ifdef CONFIG_FPE_NWFPE_XP
36062306a36Sopenharmony_cistatic inline floatx80 __pure getExtendedConstant(const unsigned int nIndex)
36162306a36Sopenharmony_ci{
36262306a36Sopenharmony_ci	extern const floatx80 floatx80Constant[];
36362306a36Sopenharmony_ci	return floatx80Constant[nIndex];
36462306a36Sopenharmony_ci}
36562306a36Sopenharmony_ci#endif
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_cistatic inline float64 __pure getDoubleConstant(const unsigned int nIndex)
36862306a36Sopenharmony_ci{
36962306a36Sopenharmony_ci	extern const float64 float64Constant[];
37062306a36Sopenharmony_ci	return float64Constant[nIndex];
37162306a36Sopenharmony_ci}
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_cistatic inline float32 __pure getSingleConstant(const unsigned int nIndex)
37462306a36Sopenharmony_ci{
37562306a36Sopenharmony_ci	extern const float32 float32Constant[];
37662306a36Sopenharmony_ci	return float32Constant[nIndex];
37762306a36Sopenharmony_ci}
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_cistatic inline unsigned int getTransferLength(const unsigned int opcode)
38062306a36Sopenharmony_ci{
38162306a36Sopenharmony_ci	unsigned int nRc;
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci	switch (opcode & MASK_TRANSFER_LENGTH) {
38462306a36Sopenharmony_ci	case 0x00000000:
38562306a36Sopenharmony_ci		nRc = 1;
38662306a36Sopenharmony_ci		break;		/* single precision */
38762306a36Sopenharmony_ci	case 0x00008000:
38862306a36Sopenharmony_ci		nRc = 2;
38962306a36Sopenharmony_ci		break;		/* double precision */
39062306a36Sopenharmony_ci	case 0x00400000:
39162306a36Sopenharmony_ci		nRc = 3;
39262306a36Sopenharmony_ci		break;		/* extended precision */
39362306a36Sopenharmony_ci	default:
39462306a36Sopenharmony_ci		nRc = 0;
39562306a36Sopenharmony_ci	}
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci	return (nRc);
39862306a36Sopenharmony_ci}
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_cistatic inline unsigned int getRegisterCount(const unsigned int opcode)
40162306a36Sopenharmony_ci{
40262306a36Sopenharmony_ci	unsigned int nRc;
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci	switch (opcode & MASK_REGISTER_COUNT) {
40562306a36Sopenharmony_ci	case 0x00000000:
40662306a36Sopenharmony_ci		nRc = 4;
40762306a36Sopenharmony_ci		break;
40862306a36Sopenharmony_ci	case 0x00008000:
40962306a36Sopenharmony_ci		nRc = 1;
41062306a36Sopenharmony_ci		break;
41162306a36Sopenharmony_ci	case 0x00400000:
41262306a36Sopenharmony_ci		nRc = 2;
41362306a36Sopenharmony_ci		break;
41462306a36Sopenharmony_ci	case 0x00408000:
41562306a36Sopenharmony_ci		nRc = 3;
41662306a36Sopenharmony_ci		break;
41762306a36Sopenharmony_ci	default:
41862306a36Sopenharmony_ci		nRc = 0;
41962306a36Sopenharmony_ci	}
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci	return (nRc);
42262306a36Sopenharmony_ci}
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_cistatic inline unsigned int getRoundingPrecision(const unsigned int opcode)
42562306a36Sopenharmony_ci{
42662306a36Sopenharmony_ci	unsigned int nRc;
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci	switch (opcode & MASK_ROUNDING_PRECISION) {
42962306a36Sopenharmony_ci	case 0x00000000:
43062306a36Sopenharmony_ci		nRc = 1;
43162306a36Sopenharmony_ci		break;
43262306a36Sopenharmony_ci	case 0x00000080:
43362306a36Sopenharmony_ci		nRc = 2;
43462306a36Sopenharmony_ci		break;
43562306a36Sopenharmony_ci	case 0x00080000:
43662306a36Sopenharmony_ci		nRc = 3;
43762306a36Sopenharmony_ci		break;
43862306a36Sopenharmony_ci	default:
43962306a36Sopenharmony_ci		nRc = 0;
44062306a36Sopenharmony_ci	}
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci	return (nRc);
44362306a36Sopenharmony_ci}
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_cistatic inline unsigned int getDestinationSize(const unsigned int opcode)
44662306a36Sopenharmony_ci{
44762306a36Sopenharmony_ci	unsigned int nRc;
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci	switch (opcode & MASK_DESTINATION_SIZE) {
45062306a36Sopenharmony_ci	case 0x00000000:
45162306a36Sopenharmony_ci		nRc = typeSingle;
45262306a36Sopenharmony_ci		break;
45362306a36Sopenharmony_ci	case 0x00000080:
45462306a36Sopenharmony_ci		nRc = typeDouble;
45562306a36Sopenharmony_ci		break;
45662306a36Sopenharmony_ci	case 0x00080000:
45762306a36Sopenharmony_ci		nRc = typeExtended;
45862306a36Sopenharmony_ci		break;
45962306a36Sopenharmony_ci	default:
46062306a36Sopenharmony_ci		nRc = typeNone;
46162306a36Sopenharmony_ci	}
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci	return (nRc);
46462306a36Sopenharmony_ci}
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ciextern const float64 float64Constant[];
46762306a36Sopenharmony_ciextern const float32 float32Constant[];
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci#endif
470