+ assignadjust (ParamType, &Param);
+
+ /* Check if the parameter is a constant array of some type, or a numeric
+ * address cast to a pointer.
+ */
+ CodeFlags = 0;
+ ParamName = Param.Name;
+ if ((IsTypeArray (Param.Type) && (Param.Flags & E_MCONST) != 0) ||
+ (IsTypePtr (Param.Type) && Param.Flags == (E_MCONST | E_TCONST))) {
+
+ /* Check which type of constant it is */
+ switch (Param.Flags & E_MCTYPE) {
+
+ case E_TCONST:
+ /* Numerical address */
+ CodeFlags |= CF_CONST | CF_ABSOLUTE;
+ break;
+
+ case E_TREGISTER:
+ /* Register variable */
+ CodeFlags |= CF_CONST | CF_REGVAR;
+ break;
+
+ case E_TGLAB:
+ /* Global label */
+ CodeFlags |= CF_CONST | CF_EXTERNAL;
+ break;
+
+ case E_TLLAB:
+ /* Local symbol */
+ CodeFlags |= CF_CONST | CF_STATIC;
+ break;
+
+ case E_TLIT:
+ /* A literal of some kind. If string literals are read only,
+ * we can calculate the length of the string and remove it
+ * from the literal pool. Otherwise we have to calculate the
+ * length at runtime.
+ */
+ if (!WriteableStrings) {
+ /* String literals are const */
+ ExprDesc Length;
+ MakeConstIntExpr (&Length, strlen (GetLiteral (Param.ConstVal)));
+ ResetLiteralPoolOffs (Param.ConstVal);
+ exprhs (CF_NONE, 0, &Length);
+ goto ExitPoint;
+ } else {
+ CodeFlags |= CF_CONST | CF_STATIC;
+ ParamName = LiteralPoolLabel;
+ }
+ break;
+
+ default:
+ Internal ("Unknown constant type: %04X", Param.Flags);
+ }
+
+ } else {
+
+ /* Not an array with a constant address. Load parameter into primary */
+ exprhs (CF_NONE, k, &Param);
+
+ }