diff options
Diffstat (limited to 'gas/config/tc-ia64.c')
-rw-r--r-- | gas/config/tc-ia64.c | 164 |
1 files changed, 132 insertions, 32 deletions
diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index c7c609a..a0ec508 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -528,7 +528,7 @@ static int regdepslen = 0; static int regdepstotlen = 0; static const char *dv_mode[] = { "RAW", "WAW", "WAR" }; static const char *dv_sem[] = { "none", "implied", "impliedf", - "data", "instr", "specific", "other" }; + "data", "instr", "specific", "stop", "other" }; static const char *dv_cmp_type[] = { "none", "OR", "AND" }; /* Current state of PR mutexation */ @@ -6921,26 +6921,129 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note) } break; + /* This is the same as IA64_RS_PRr, except that the register range is + from 1 - 15, and there are no rotating register reads/writes here. */ case IA64_RS_PR: if (note == 0) { - if (idesc->operands[0] == IA64_OPND_PR_ROT) + for (i = 1; i < 16; i++) { - for (i = 16; i < 63; i++) + specs[count] = tmpl; + specs[count++].index = i; + } + } + else if (note == 7) + { + valueT mask = 0; + /* Mark only those registers indicated by the mask. */ + if (rsrc_write) + { + mask = CURR_SLOT.opnd[2].X_add_number; + for (i = 1; i < 16; i++) + if (mask & ((valueT) 1 << i)) + { + specs[count] = tmpl; + specs[count++].index = i; + } + } + else + { + UNHANDLED; + } + } + else if (note == 11) /* note 11 implies note 1 as well */ + { + if (rsrc_write) + { + for (i = 0; i < idesc->num_outputs; i++) + { + if (idesc->operands[i] == IA64_OPND_P1 + || idesc->operands[i] == IA64_OPND_P2) + { + int regno = CURR_SLOT.opnd[i].X_add_number - REG_P; + if (regno >= 1 && regno < 16) + { + specs[count] = tmpl; + specs[count++].index = regno; + } + } + } + } + else + { + UNHANDLED; + } + } + else if (note == 12) + { + if (CURR_SLOT.qp_regno >= 1 && CURR_SLOT.qp_regno < 16) + { + specs[count] = tmpl; + specs[count++].index = CURR_SLOT.qp_regno; + } + } + else if (note == 1) + { + if (rsrc_write) + { + int p1 = CURR_SLOT.opnd[0].X_add_number - REG_P; + int p2 = CURR_SLOT.opnd[1].X_add_number - REG_P; + int or_andcm = strstr(idesc->name, "or.andcm") != NULL; + int and_orcm = strstr(idesc->name, "and.orcm") != NULL; + + if ((idesc->operands[0] == IA64_OPND_P1 + || idesc->operands[0] == IA64_OPND_P2) + && p1 >= 1 && p1 < 16) { specs[count] = tmpl; - specs[count++].index = i; + specs[count].cmp_type = + (or_andcm ? CMP_OR : (and_orcm ? CMP_AND : CMP_NONE)); + specs[count++].index = p1; + } + if ((idesc->operands[1] == IA64_OPND_P1 + || idesc->operands[1] == IA64_OPND_P2) + && p2 >= 1 && p2 < 16) + { + specs[count] = tmpl; + specs[count].cmp_type = + (or_andcm ? CMP_AND : (and_orcm ? CMP_OR : CMP_NONE)); + specs[count++].index = p2; } } else { - for (i = 1; i < 63; i++) + if (CURR_SLOT.qp_regno >= 1 && CURR_SLOT.qp_regno < 16) { specs[count] = tmpl; - specs[count++].index = i; + specs[count++].index = CURR_SLOT.qp_regno; + } + if (idesc->operands[1] == IA64_OPND_PR) + { + for (i = 1; i < 16; i++) + { + specs[count] = tmpl; + specs[count++].index = i; + } } } } + else + { + UNHANDLED; + } + break; + + /* This is the general case for PRs. IA64_RS_PR and IA64_RS_PR63 are + simplified cases of this. */ + case IA64_RS_PRr: + if (note == 0) + { + for (i = 16; i < 63; i++) + { + specs[count] = tmpl; + specs[count++].index = i; + } + } else if (note == 7) { valueT mask = 0; @@ -6949,16 +7052,12 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note) && idesc->operands[0] == IA64_OPND_PR) { mask = CURR_SLOT.opnd[2].X_add_number; - if (mask & ((valueT) 1 << 16)) - mask |= ~(valueT) 0xffff; - for (i = 1; i < 63; i++) - { - if (mask & ((valueT) 1 << i)) - { - specs[count] = tmpl; - specs[count++].index = i; - } - } + if (mask & ((valueT) 1<<16)) + for (i = 16; i < 63; i++) + { + specs[count] = tmpl; + specs[count++].index = i; + } } else if (rsrc_write && idesc->operands[0] == IA64_OPND_PR_ROT) @@ -6984,7 +7083,7 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note) || idesc->operands[i] == IA64_OPND_P2) { int regno = CURR_SLOT.opnd[i].X_add_number - REG_P; - if (regno != 0) + if (regno >= 16 && regno < 63) { specs[count] = tmpl; specs[count++].index = regno; @@ -6999,7 +7098,7 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note) } else if (note == 12) { - if (CURR_SLOT.qp_regno != 0) + if (CURR_SLOT.qp_regno >= 16 && CURR_SLOT.qp_regno < 63) { specs[count] = tmpl; specs[count++].index = CURR_SLOT.qp_regno; @@ -7016,7 +7115,7 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note) if ((idesc->operands[0] == IA64_OPND_P1 || idesc->operands[0] == IA64_OPND_P2) - && p1 != 0 && p1 != 63) + && p1 >= 16 && p1 < 63) { specs[count] = tmpl; specs[count].cmp_type = @@ -7025,7 +7124,7 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note) } if ((idesc->operands[1] == IA64_OPND_P1 || idesc->operands[1] == IA64_OPND_P2) - && p2 != 0 && p2 != 63) + && p2 >= 16 && p2 < 63) { specs[count] = tmpl; specs[count].cmp_type = @@ -7035,14 +7134,14 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note) } else { - if (CURR_SLOT.qp_regno != 0) + if (CURR_SLOT.qp_regno >= 16 && CURR_SLOT.qp_regno < 63) { specs[count] = tmpl; specs[count++].index = CURR_SLOT.qp_regno; } if (idesc->operands[1] == IA64_OPND_PR) { - for (i = 1; i < 63; i++) + for (i = 16; i < 63; i++) { specs[count] = tmpl; specs[count++].index = i; @@ -7436,11 +7535,21 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note) } break; + /* This is the same as IA64_RS_PRr, except simplified to account for + the fact that there is only one register. */ case IA64_RS_PR63: if (note == 0) { specs[count++] = tmpl; } + else if (note == 7) + { + valueT mask = 0; + if (idesc->operands[2] == IA64_OPND_IMM17) + mask = CURR_SLOT.opnd[2].X_add_number; + if (mask & ((valueT) 1 << 63)) + specs[count++] = tmpl; + } else if (note == 11) { if ((idesc->operands[0] == IA64_OPND_P1 @@ -7458,16 +7567,6 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note) specs[count++] = tmpl; } } - else if (note == 7) - { - valueT mask = 0; - if (idesc->operands[2] == IA64_OPND_IMM17) - mask = CURR_SLOT.opnd[2].X_add_number; - if (mask & ((valueT) 1 << 63)) - { - specs[count++] = tmpl; - } - } else if (note == 1) { if (rsrc_write) @@ -8407,6 +8506,7 @@ mark_resources (idesc) if (add_only_qp_reads && !(dep->mode == IA64_DV_WAR && (dep->specifier == IA64_RS_PR + || dep->specifier == IA64_RS_PRr || dep->specifier == IA64_RS_PR63))) continue; |