mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
8028401: PPC (part 117): Improve usability of adlc and format() functionality
Add additional, more verbose syntax checks in adlc. Fix printing constant's problem in format(). Reviewed-by: kvn
This commit is contained in:
parent
fa597af116
commit
f9a0d6a4b5
5 changed files with 57 additions and 16 deletions
|
@ -3996,13 +3996,11 @@ void ADLParser::effect_parse(InstructForm *instr) {
|
||||||
//------------------------------expand_parse-----------------------------------
|
//------------------------------expand_parse-----------------------------------
|
||||||
ExpandRule* ADLParser::expand_parse(InstructForm *instr) {
|
ExpandRule* ADLParser::expand_parse(InstructForm *instr) {
|
||||||
char *ident, *ident2;
|
char *ident, *ident2;
|
||||||
OperandForm *oper;
|
|
||||||
InstructForm *ins;
|
|
||||||
NameAndList *instr_and_operands = NULL;
|
NameAndList *instr_and_operands = NULL;
|
||||||
ExpandRule *exp = new ExpandRule();
|
ExpandRule *exp = new ExpandRule();
|
||||||
|
|
||||||
// Expand is a block containing an ordered list of instructions, each of
|
// Expand is a block containing an ordered list of operands with initializers,
|
||||||
// which has an ordered list of operands.
|
// or instructions, each of which has an ordered list of operands.
|
||||||
// Check for block delimiter
|
// Check for block delimiter
|
||||||
skipws(); // Skip leading whitespace
|
skipws(); // Skip leading whitespace
|
||||||
if ((_curchar != '%')
|
if ((_curchar != '%')
|
||||||
|
@ -4016,12 +4014,30 @@ ExpandRule* ADLParser::expand_parse(InstructForm *instr) {
|
||||||
if (ident == NULL) {
|
if (ident == NULL) {
|
||||||
parse_err(SYNERR, "identifier expected at %c\n", _curchar);
|
parse_err(SYNERR, "identifier expected at %c\n", _curchar);
|
||||||
continue;
|
continue;
|
||||||
} // Check that you have a valid instruction
|
}
|
||||||
|
|
||||||
|
// Check whether we should parse an instruction or operand.
|
||||||
const Form *form = _globalNames[ident];
|
const Form *form = _globalNames[ident];
|
||||||
ins = form ? form->is_instruction() : NULL;
|
bool parse_oper = false;
|
||||||
if (ins == NULL) {
|
bool parse_ins = false;
|
||||||
|
if (form == NULL) {
|
||||||
|
skipws();
|
||||||
|
// Check whether this looks like an instruction specification. If so,
|
||||||
|
// just parse the instruction. The declaration of the instruction is
|
||||||
|
// not needed here.
|
||||||
|
if (_curchar == '(') parse_ins = true;
|
||||||
|
} else if (form->is_instruction()) {
|
||||||
|
parse_ins = true;
|
||||||
|
} else if (form->is_operand()) {
|
||||||
|
parse_oper = true;
|
||||||
|
} else {
|
||||||
|
parse_err(SYNERR, "instruction/operand name expected at %s\n", ident);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parse_oper) {
|
||||||
// This is a new operand
|
// This is a new operand
|
||||||
oper = form ? form->is_operand() : NULL;
|
OperandForm *oper = form->is_operand();
|
||||||
if (oper == NULL) {
|
if (oper == NULL) {
|
||||||
parse_err(SYNERR, "instruction/operand name expected at %s\n", ident);
|
parse_err(SYNERR, "instruction/operand name expected at %s\n", ident);
|
||||||
continue;
|
continue;
|
||||||
|
@ -4056,6 +4072,7 @@ ExpandRule* ADLParser::expand_parse(InstructForm *instr) {
|
||||||
skipws();
|
skipws();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
assert(parse_ins, "sanity");
|
||||||
// Add instruction to list
|
// Add instruction to list
|
||||||
instr_and_operands = new NameAndList(ident);
|
instr_and_operands = new NameAndList(ident);
|
||||||
// Grab operands, build nameList of them, and then put into dictionary
|
// Grab operands, build nameList of them, and then put into dictionary
|
||||||
|
@ -4079,7 +4096,7 @@ ExpandRule* ADLParser::expand_parse(InstructForm *instr) {
|
||||||
parse_err(SYNERR, "operand name expected at %s\n", ident2);
|
parse_err(SYNERR, "operand name expected at %s\n", ident2);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
oper = form2->is_operand();
|
OperandForm *oper = form2->is_operand();
|
||||||
if (oper == NULL && !form2->is_opclass()) {
|
if (oper == NULL && !form2->is_opclass()) {
|
||||||
parse_err(SYNERR, "operand name expected at %s\n", ident2);
|
parse_err(SYNERR, "operand name expected at %s\n", ident2);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1276,11 +1276,11 @@ void InstructForm::rep_var_format(FILE *fp, const char *rep_var) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (strcmp(rep_var, "constantoffset") == 0) {
|
if (strcmp(rep_var, "constantoffset") == 0) {
|
||||||
fprintf(fp, "st->print(\"#%%d\", constant_offset());\n");
|
fprintf(fp, "st->print(\"#%%d\", constant_offset_unchecked());\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (strcmp(rep_var, "constantaddress") == 0) {
|
if (strcmp(rep_var, "constantaddress") == 0) {
|
||||||
fprintf(fp, "st->print(\"constant table base + #%%d\", constant_offset());\n");
|
fprintf(fp, "st->print(\"constant table base + #%%d\", constant_offset_unchecked());\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1570,6 +1570,13 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
|
||||||
new_id = expand_instr->name();
|
new_id = expand_instr->name();
|
||||||
|
|
||||||
InstructForm* expand_instruction = (InstructForm*)globalAD->globalNames()[new_id];
|
InstructForm* expand_instruction = (InstructForm*)globalAD->globalNames()[new_id];
|
||||||
|
|
||||||
|
if (!expand_instruction) {
|
||||||
|
globalAD->syntax_err(node->_linenum, "In %s: instruction %s used in expand not declared\n",
|
||||||
|
node->_ident, new_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (expand_instruction->has_temps()) {
|
if (expand_instruction->has_temps()) {
|
||||||
globalAD->syntax_err(node->_linenum, "In %s: expand rules using instructs with TEMPs aren't supported: %s",
|
globalAD->syntax_err(node->_linenum, "In %s: expand rules using instructs with TEMPs aren't supported: %s",
|
||||||
node->_ident, new_id);
|
node->_ident, new_id);
|
||||||
|
@ -1628,6 +1635,13 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
|
||||||
// Use 'parameter' at current position in list of new instruction's formals
|
// Use 'parameter' at current position in list of new instruction's formals
|
||||||
// instead of 'opid' when looking up info internal to new_inst
|
// instead of 'opid' when looking up info internal to new_inst
|
||||||
const char *parameter = formal_lst->iter();
|
const char *parameter = formal_lst->iter();
|
||||||
|
if (!parameter) {
|
||||||
|
globalAD->syntax_err(node->_linenum, "Operand %s of expand instruction %s has"
|
||||||
|
" no equivalent in new instruction %s.",
|
||||||
|
opid, node->_ident, new_inst->_ident);
|
||||||
|
assert(0, "Wrong expand");
|
||||||
|
}
|
||||||
|
|
||||||
// Check for an operand which is created in the expand rule
|
// Check for an operand which is created in the expand rule
|
||||||
if ((exp_pos = node->_exprule->_newopers.index(opid)) != -1) {
|
if ((exp_pos = node->_exprule->_newopers.index(opid)) != -1) {
|
||||||
new_pos = new_inst->operand_position(parameter,Component::USE);
|
new_pos = new_inst->operand_position(parameter,Component::USE);
|
||||||
|
@ -2103,6 +2117,9 @@ public:
|
||||||
if (strcmp(rep_var,"$reg") == 0 || reg_conversion(rep_var) != NULL) {
|
if (strcmp(rep_var,"$reg") == 0 || reg_conversion(rep_var) != NULL) {
|
||||||
_reg_status = LITERAL_ACCESSED;
|
_reg_status = LITERAL_ACCESSED;
|
||||||
} else {
|
} else {
|
||||||
|
_AD.syntax_err(_encoding._linenum,
|
||||||
|
"Invalid access to literal register parameter '%s' in %s.\n",
|
||||||
|
rep_var, _encoding._name);
|
||||||
assert( false, "invalid access to literal register parameter");
|
assert( false, "invalid access to literal register parameter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2112,7 +2129,9 @@ public:
|
||||||
if (strcmp(rep_var,"$constant") == 0) {
|
if (strcmp(rep_var,"$constant") == 0) {
|
||||||
_constant_status = LITERAL_ACCESSED;
|
_constant_status = LITERAL_ACCESSED;
|
||||||
} else {
|
} else {
|
||||||
assert( false, "invalid access to literal constant parameter");
|
_AD.syntax_err(_encoding._linenum,
|
||||||
|
"Invalid access to literal constant parameter '%s' in %s.\n",
|
||||||
|
rep_var, _encoding._name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end replacement and/or subfield
|
} // end replacement and/or subfield
|
||||||
|
|
|
@ -505,6 +505,9 @@ int MachConstantNode::constant_offset() {
|
||||||
return _constant.offset();
|
return _constant.offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MachConstantNode::constant_offset_unchecked() const {
|
||||||
|
return _constant.offset();
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
|
|
@ -416,6 +416,8 @@ public:
|
||||||
|
|
||||||
int constant_offset();
|
int constant_offset();
|
||||||
int constant_offset() const { return ((MachConstantNode*) this)->constant_offset(); }
|
int constant_offset() const { return ((MachConstantNode*) this)->constant_offset(); }
|
||||||
|
// Unchecked version to avoid assertions in debug output.
|
||||||
|
int constant_offset_unchecked() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------MachUEPNode-----------------------------------
|
//------------------------------MachUEPNode-----------------------------------
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue