-\f
-/* Default insertion routine.
-
- ATTRS is a mask of the boolean attributes.
- LENGTH is the length of VALUE in bits.
- TOTAL_LENGTH is the total length of the insn (currently 8,16,32).
-
- The result is an error message or NULL if success. */
-
-/* ??? This duplicates functionality with bfd's howto table and
- bfd_install_relocation. */
-/* ??? For architectures where insns can be representable as ints,
- store insn in `field' struct and add registers, etc. while parsing? */
-
-static const char *
-insert_normal (value, attrs, start, length, total_length, buffer)
- long value;
- unsigned int attrs;
- int start;
- int length;
- int total_length;
- char * buffer;
-{
- bfd_vma x;
- static char buf[100];
-
- /* Ensure VALUE will fit. */
- if ((attrs & (1 << CGEN_OPERAND_UNSIGNED)) != 0)
- {
- unsigned long max = (1 << length) - 1;
- if ((unsigned long) value > max)
- {
- const char *err = "operand out of range (%lu not between 0 and %lu)";
-
- sprintf (buf, err, value, max);
- return buf;
- }
- }
- else
- {
- long min = - (1 << (length - 1));
- long max = (1 << (length - 1)) - 1;
- if (value < min || value > max)
- {
- const char *err = "operand out of range (%ld not between %ld and %ld)";
-
- sprintf (buf, err, value, min, max);
- return buf;
- }
- }
-
-#if 0 /*def CGEN_INT_INSN*/
- *buffer |= ((value & ((1 << length) - 1))
- << (total_length - (start + length)));
-#else
- switch (total_length)
- {
- case 8:
- x = * (unsigned char *) buffer;
- break;
- case 16:
- if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
- x = bfd_getb16 (buffer);
- else
- x = bfd_getl16 (buffer);
- break;
- case 32:
- if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
- x = bfd_getb32 (buffer);
- else
- x = bfd_getl32 (buffer);
- break;
- default :
- abort ();
- }
-
- x |= ((value & ((1 << length) - 1))
- << (total_length - (start + length)));
-
- switch (total_length)
- {
- case 8:
- * buffer = value;
- break;
- case 16:
- if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
- bfd_putb16 (x, buffer);
- else
- bfd_putl16 (x, buffer);
- break;
- case 32:
- if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
- bfd_putb32 (x, buffer);
- else
- bfd_putl32 (x, buffer);
- break;
- default :
- abort ();
- }
-#endif
-
- return NULL;
-}