• No results found

Format: (qp) cmp.crel.ctype p1, p2 = r2, r3 register_form A6

(qp) cmp.crel.ctype p1, p2 = imm8, r3 imm8_form A8

(qp) cmp.crel.ctype p1, p2 = r0, r3 parallel_inequality_form A7

(qp) cmp.crel.ctype p1, p2 = r3, r0 pseudo-op

Description: The two source operands are compared for one of ten relations specified by crel. This produces a boolean result which is 1 if the comparison condition is true, and 0 otherwise. This result is written to the two predicate register destinations, p1 and p2.

The way the result is written to the destinations is determined by the compare type specified by ctype.

The compare types describe how the predicate targets are updated based on the result of the comparison. The normal type simply writes the compare result to one target, and the complement to the other. The parallel types update the targets only for a particular comparison result. This allows multiple simultaneous OR-type or multiple simultaneous AND-type compares to target the same predicate register.

The unc type is special in that it first initializes both predicate targets to 0, independent

of the qualifying predicate. It then operates the same as the normal type. The behavior

of the compare types is described in Table 2-15. A blank entry indicates the predicate target is left unchanged.

In the register_form the first operand is GR r2; in the imm8_form the first operand is

taken from the sign-extended imm8 encoding field; and in the parallel_inequality_form

the first operand must be GR 0. The parallel_inequality_form is only used when the compare type is one of the parallel types, and the relation is an inequality (>, >=, <, <=). See below.

If the two predicate register destinations are the same (p1 and p2 specify the same

predicate register), the instruction will take an Illegal Operation fault, if the qualifying predicate is 1, or if the compare type is unc.

Of the ten relations, not all are directly implemented in hardware. Some are actually pseudo-ops. For these, the assembler simply switches the source operand specifiers and/or switches the predicate target specifiers and uses an implemented relation. For some of the pseudo-op compares in the imm8_form, the assembler subtracts 1 from the immediate value, making the allowed immediate range slightly different. Of the six parallel compare types, three of the types are actually pseudo-ops. The assembler

Table 2-15. Comparison Types

ctype Pseudo-op of PR[qp]==0 PR[qp]==1 Result==0, No Source NaTs Result==1, No Source NaTs One or More Source NaTs PR[p1] PR[p2] PR[p1] PR[p2] PR[p1] PR[p2] PR[p1] PR[p2] none 0 1 1 0 0 0 unc 0 0 0 1 1 0 0 0 or 1 1 and 0 0 0 0 or.andcm 1 0 orcm or 1 1 andcm and 0 0 0 0 and.orcm or.andcm 0 1

cmp

simply uses the negative relation with an implemented type. The implemented relations and how the pseudo-ops map onto them are shown in Table 2-16 (for normal and unc type compares), and Table 2-17 (for parallel type compares).

The parallel compare types can be used only with a restricted set of relations and operands. They can be used with equal and not-equal comparisons between two registers or between a register and an immediate, or they can be used with inequality comparisons between a register and GR 0. Unsigned relations are not provided, since they are not of much use when one of the operands is zero. For the parallel inequality comparisons, hardware only directly implements the ones where the first operand (GR

r2) is GR 0. Comparisons where the second operand is GR 0 are pseudo-ops for which

the assembler switches the register specifiers and uses the opposite relation.

Table 2-16. 64-bit Comparison Relations for Normal and unc Compares

crel Compare Relation(a rel b) Register Form is apseudo-op of Immediate Form is a pseudo-op of Immediate Range

eq a == b -128 .. 127 ne a != b eq p1  p2 eq p1  p2 -128 .. 127 lt a < b signed -128 .. 127 le a <= b lt a  b p1  p2 lt a-1 -127 .. 128 gt a > b lt a  b lt a-1 p1  p2 -127 .. 128 ge a >= b lt p1  p2 lt p1  p2 -128 .. 127 ltu a < b unsigned 0 .. 127, 264-128 .. 264-1 leu a <= b ltu a  b p1  p2 ltu a-1 1 .. 128,

264-127 .. 264

gtu a > b ltu a  b ltu a-1 p1  p2 1 .. 128, 264-127 .. 264 geu a >= b ltu p1  p2 ltu p1  p2 0 .. 127,

264-128 .. 264-1

Table 2-17. 64-bit Comparison Relations for Parallel Compares

crel Compare Relation

(a rel b)

Register Form is a

pseudo-op of Immediate Range

eq a == b -128 .. 127 ne a != b -128 .. 127

lt 0 < b signed no immediate forms

lt a < 0 gt a  b le 0 <= b le a <= 0 ge a  b gt 0 > b gt a > 0 lt a  b ge 0 >= b ge a >= 0 le a  b

Operation: if (PR[qp]) { if (p1 == p2)

illegal_operation_fault();

tmp_nat = (register_form ? GR[r2].nat : 0) || GR[r3].nat; if (register_form) tmp_src = GR[r2]; else if (imm8_form) tmp_src = sign_ext(imm8, 8); else // parallel_inequality_form tmp_src = 0;

if (crel == ‘eq’) tmp_rel = tmp_src == GR[r3];

else if (crel == ‘ne’) tmp_rel = tmp_src != GR[r3];

else if (crel == ‘lt’) tmp_rel = lesser_signed(tmp_src, GR[r3]); else if (crel == ‘le’) tmp_rel = lesser_equal_signed(tmp_src, GR[r3]);

else if (crel == ‘gt’) tmp_rel = greater_signed(tmp_src, GR[r3]); else if (crel == ‘ge’) tmp_rel = greater_equal_signed(tmp_src, GR[r3]);

else if (crel == ‘ltu’) tmp_rel = lesser(tmp_src, GR[r3]); else if (crel == ‘leu’) tmp_rel = lesser_equal(tmp_src, GR[r3]);

else if (crel == ‘gtu’) tmp_rel = greater(tmp_src, GR[r3]);

else tmp_rel = greater_equal(tmp_src, GR[r3]);//‘geu’

switch (ctype) {

case ‘and’: // and-type compare

if (tmp_nat || !tmp_rel) { PR[p1] = 0;

PR[p2] = 0;

} break;

case ‘or’: // or-type compare

if (!tmp_nat && tmp_rel) { PR[p1] = 1;

PR[p2] = 1;

} break;

case ‘or.andcm’: // or.andcm-type compare

if (!tmp_nat && tmp_rel) { PR[p1] = 1;

PR[p2] = 0;

} break;

case ‘unc’: // unc-type compare

default: // normal compare

if (tmp_nat) { PR[p1] = 0; PR[p2] = 0; } else { PR[p1] = tmp_rel; PR[p2] = !tmp_rel; } break; } } else { if (ctype == ‘unc’) { if (p1 == p2)

cmp illegal_operation_fault(); PR[p1] = 0; PR[p2] = 0; } }

Related documents