?? RIGHT := 110 ??
MODULE ocm$normalize_binding_sec_value;
*copyc osd$default_pragmats
?? PUSH (LISTEXT := ON) ??
*copyc oce$metapatch_generator_errors
*copyc oct$code_section_directory
*copyc oct$section_directory
*copyc llt$relocation
*copyc ost$status
*copyc osp$set_status_abnormal
*copyc ocp$new_offset
?? POP ??

*copyc och$normalize_binding_sec_value
  PROCEDURE [XDCL] ocp$normalize_binding_sec_value (code_section_directory: oct$code_directory_item;
        module_code_section_directory: ^oct$module_code_sections;
        relocation: llt$relocation_item;
        section_directory: ^oct$section_directory;
    VAR status: ost$status);

    VAR
      two_byte_container: ^packed record
        case boolean of
        = TRUE =
          two_byte: 0 .. 0ffff(16),
        = FALSE =
          sign_bit: boolean,
        casend,
      recend,

      three_byte_container: ^packed record
        case boolean of
        = TRUE =
          three_byte: 0 .. 0ffffff(16),
        = FALSE =
          sign_bit: boolean,
        casend,
      recend,

      halfword_container: ^packed record
        case boolean of
        = TRUE =
          halfword: 0 .. 0ffffffff(16),
        = FALSE =
          sign_bit: boolean,
        casend,
      recend,

      word_container: ^packed record
        case boolean of
        = TRUE =
          word: integer,
        = FALSE =
          sign_bit: boolean,
        casend,
      recend,

      d_field_container: ^packed record
        case boolean of
        = TRUE =
          i_portion: 0 .. 0f(16),
          d_portion: 0 .. 0fff(16),
        = FALSE =
          filler: 0 .. 0f(16),
          sign_bit: boolean,
        casend,
      recend,

      q_field_container: ^packed record
        case boolean of
        = TRUE =
          q_field: oct$q_field,
        = FALSE =
          sign_bit: boolean,
        casend,
      recend,

      long_d_field_container: ^packed record
        case boolean of
        = TRUE =
          long_d_field: 0 .. 0ffffff(16),
        = FALSE =
          sign_bit: boolean,
        casend,
      recend,

      bs_offset: integer,
      bs_field: ^cell,
      i: llt$section_ordinal,
      index: llt$section_ordinal,
      offset: integer,
      ring: integer,
      section_found: boolean,
      segment: integer,
      sign_bit_on: boolean;

    IF code_section_directory.last_entry_number >= code_section_directory.first_entry_number THEN

      i := code_section_directory.first_entry_number;

      REPEAT
        section_found := (module_code_section_directory^ [i].section_ordinal = relocation.section_ordinal);
        i := i + 1;
      UNTIL section_found OR (i > code_section_directory.last_entry_number);

      IF section_found THEN

        index := i - 1;
        offset := #offset (module_code_section_directory^ [index].start_of_section) + relocation.offset;
        ring := #ring (module_code_section_directory^ [index].start_of_section);
        segment := #segment (module_code_section_directory^ [index].start_of_section);
        bs_field := #address (ring, segment, offset);

        CASE relocation.container OF
        = llc$two_bytes =
          two_byte_container := bs_field;
          bs_offset := two_byte_container^.two_byte;
          sign_bit_on := two_byte_container^.sign_bit;

        = llc$three_bytes =
          three_byte_container := bs_field;
          bs_offset := three_byte_container^.three_byte;
          sign_bit_on := three_byte_container^.sign_bit;

        = llc$four_bytes =
          halfword_container := bs_field;
          bs_offset := halfword_container^.halfword;
          sign_bit_on := halfword_container^.sign_bit;

        = llc$eight_bytes =
          word_container := bs_field;
          bs_offset := word_container^.word;
          sign_bit_on := word_container^.sign_bit;

        = llc$180_d_field =
          d_field_container := bs_field;
          bs_offset := d_field_container^.d_portion;
          sign_bit_on := d_field_container^.sign_bit;

        = llc$180_q_field =
          q_field_container := bs_field;
          bs_offset := q_field_container^.q_field;
          sign_bit_on := q_field_container^.sign_bit;

        = llc$180_long_d_field =
          long_d_field_container := bs_field;
          bs_offset := long_d_field_container^.long_d_field;
          sign_bit_on := long_d_field_container^.sign_bit;

        ELSE

          osp$set_status_abnormal (occ$status_id, oce$invalid_container, ' ', status);
          RETURN;
        CASEND;

        CASE relocation.address OF

        = llc$byte_positive =
          ;

        = llc$two_byte_positive =
          bs_offset := bs_offset * 2;

        = llc$four_byte_positive =
          bs_offset := bs_offset * 4;

        = llc$eight_byte_positive =
          bs_offset := bs_offset * 8;

        = llc$byte_signed =
          IF sign_bit_on THEN
            osp$set_status_abnormal (occ$status_id, oce$invalid_relocation_address, ' ', status);
            RETURN;
          IFEND;

        = llc$two_byte_signed =
          bs_offset := bs_offset * 2;
          IF sign_bit_on THEN
            osp$set_status_abnormal (occ$status_id, oce$invalid_relocation_address, ' ', status);
            RETURN;
          IFEND;

        = llc$four_byte_signed =
          bs_offset := bs_offset * 4;
          IF sign_bit_on THEN
            osp$set_status_abnormal (occ$status_id, oce$invalid_relocation_address, ' ', status);
            RETURN;
          IFEND;

        = llc$eight_byte_signed =
          bs_offset := bs_offset * 8;
          IF sign_bit_on THEN
            osp$set_status_abnormal (occ$status_id, oce$invalid_relocation_address, ' ', status);
            RETURN;
          IFEND;

        ELSE
          osp$set_status_abnormal (occ$status_id, oce$invalid_relocation_address, ' ', status);
          RETURN;
        CASEND;

        bs_offset := ocp$new_offset (bs_offset, section_directory^ [relocation.relocating_section].
              section_offset_change_vector);
        CASE relocation.address OF

        = llc$byte_positive, llc$byte_signed =
          ;

        = llc$two_byte_positive, llc$two_byte_signed =
          bs_offset := bs_offset DIV 2;

        = llc$four_byte_positive, llc$four_byte_signed =
          bs_offset := bs_offset DIV 4;

        = llc$eight_byte_positive, llc$eight_byte_signed =
          bs_offset := bs_offset DIV 8;

        ELSE
          ;
        CASEND;

        CASE relocation.container OF

        = llc$two_bytes =
          two_byte_container^.two_byte := bs_offset;

        = llc$three_bytes =
          three_byte_container^.three_byte := bs_offset;

        = llc$four_bytes =
          halfword_container^.halfword := bs_offset;

        = llc$eight_bytes =
          word_container^.word := bs_offset;

        = llc$180_d_field =
          d_field_container^.d_portion := bs_offset;

        = llc$180_q_field =
          q_field_container^.q_field := bs_offset;

        = llc$180_long_d_field =
          long_d_field_container^.long_d_field := bs_offset;

        ELSE
          ;
        CASEND;
      IFEND;
    IFEND;
  PROCEND ocp$normalize_binding_sec_value;
MODEND ocm$normalize_binding_sec_value;
