/*
 * uvector.c.tmpl - uniform vector support code template
 *
 *   Copyright (c) 1999-2007 Shiro Kawai, All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 *   3. Neither the name of the authors nor the names of its contributors
 *      may be used to endorse or promote products derived from this
 *      software without specific prior written permission.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 *   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 *   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdlib.h>
#include <math.h>
#include <limits.h>
#include <string.h>  /* for memmove() */
#include <gauche.h>
#include <gauche/extend.h>
#include <gauche/priv/builtin-syms.h>
#include <gauche/priv/arith.h>
#include <gauche/priv/bytesP.h>
#include <gauche/endian.h>
#include <gauche/scmconst.h>

#define EXTUVECTOR_EXPORTS
#include "gauche/uvector.h"
#include "uvectorP.h"

/*
 * Generic aliasing
 */
ScmObj Scm_UVectorAlias(ScmClass *klass, ScmUVector *v,
                        ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt len = SCM_UVECTOR_SIZE(v), dstsize;

    SCM_CHECK_START_END(start, end, len);
    int reqalign = Scm_UVectorElementSize(klass);
    int srcalign = Scm_UVectorElementSize(Scm_ClassOf(SCM_OBJ(v)));
    if (reqalign < 0) {
        Scm_Error("uvector-alias requires uniform vector class, but got %S",
                  klass);
    }
    if ((start*srcalign)%reqalign != 0 || (end*srcalign)%reqalign != 0) {
        Scm_Error("aliasing %S of range (%d, %d) to %S doesn't satisfy alignemnt requirement.",
                  Scm_ClassOf(SCM_OBJ(v)), start, end, klass);
    }
    if (reqalign >= srcalign) dstsize = (end-start) / (reqalign/srcalign);
    else dstsize = (end-start) * (srcalign/reqalign);
    SCM_RETURN(Scm_MakeUVectorFull(klass,
                                   dstsize,
                                   (char*)v->elements + start*srcalign,
                                   SCM_UVECTOR_IMMUTABLE_P(v),
                                   SCM_UVECTOR_OWNER(v)));
}

/*===========================================================
 * Helper functions
 */

static void size_mismatch(const char *name, ScmObj x, ScmObj y)
{
    Scm_Error("%s: argument object sizes do not match: %S vs %S", name, x, y);
}

/* many numeric op procedures takes either uvector, vector, list or
   a constant number as the second arg.  this factors out the common
   code. */
typedef enum {
    ARGTYPE_UVECTOR,
    ARGTYPE_VECTOR,
    ARGTYPE_LIST,
    ARGTYPE_CONST
} ArgType;

static ArgType arg2_check(const char *name, ScmObj x, ScmObj y, int const_ok)
{
    int size = SCM_UVECTOR_SIZE(x);
    if (SCM_UVECTORP(y)) {
        if (SCM_UVECTOR_SIZE(y) != size) size_mismatch(name, SCM_OBJ(x), y);
        return ARGTYPE_UVECTOR;
    } else if (SCM_VECTORP(y)) {
        if (SCM_VECTOR_SIZE(y) != size) size_mismatch(name, SCM_OBJ(x), y);
        return ARGTYPE_VECTOR;
    } else if (SCM_LISTP(y)) {
        if (Scm_Length(y) != size) size_mismatch(name, SCM_OBJ(x), y);
        return ARGTYPE_LIST;
    } else if (!const_ok) {
        Scm_Error("%s: second operand must be either a matching uvector, a vector, or a list, but got %S", name, y);
    } else if (!SCM_REALP(y)) {
        Scm_Error("%s: second operand must be either a matching uvector, a vector, a list or a number, but got %S", name, y);
    }
    return ARGTYPE_CONST;
}

/****** Add, sub, mul and div (f32 and f64 only) *****/
#define s8s8_add(x, y, clamp)   clamp_s8(x+y, clamp)
#define s8s8_sub(x, y, clamp)   clamp_s8(x-y, clamp)
#define s8s8_mul(x, y, clamp)   clamp_s8(x*y, clamp)

static inline long s8g_add(long x, long y, int clamp)
{
    if (y > 255)  return range_s8hi(0, clamp);
    if (y < -256) return range_s8lo(0, clamp);
    return clamp_s8(x+y, clamp);
}

static inline long s8g_sub(long x, long y, int clamp)
{
    if (y < -255) return range_s8hi(0, clamp);
    if (y > 256)  return range_s8lo(0, clamp);
    return clamp_s8(x-y, clamp);
}

static inline long s8g_mul(long x, long y, int clamp)
{
    if (x == 0) return 0;
    if (y > 128) return (x>0)?range_s8hi(0, clamp):range_s8lo(0, clamp);
    return clamp_s8(x*y, clamp);
}

#define u8u8_add(x, y, clamp)   clamp_u8(x+y, clamp)
#define u8u8_sub(x, y, clamp)   clamp_u8((long)(x-y), clamp)
#define u8u8_mul(x, y, clamp)   clamp_u8(x*y, clamp)

static inline u_long u8g_add(u_long x, u_long y, int clamp)
{
    if (y > 255)  return range_u8hi(0, clamp);
    return clamp_u8(x+y, clamp);
}

static inline u_long u8g_sub(u_long x, u_long y, int clamp)
{
    if (y > x)   return range_u8lo(0, clamp);
    return x-y;                 /* never overflows */
}

static inline u_long u8g_mul(u_long x, u_long y, int clamp)
{
    if (x == 0) return 0;
    if (y > 255) return range_u8hi(0, clamp);
    return clamp_u8(x*y, clamp);
}

#define s16s16_add(x, y, clamp)   clamp_s16(x+y, clamp)
#define s16s16_sub(x, y, clamp)   clamp_s16(x-y, clamp)
#define s16s16_mul(x, y, clamp)   clamp_s16(x*y, clamp)

static inline long s16g_add(long x, long y, int clamp)
{
    if (y > 65535)  return range_s16hi(0, clamp);
    if (y < -65536) return range_s16lo(0, clamp);
    return clamp_s16(x+y, clamp);
}

static inline long s16g_sub(long x, long y, int clamp)
{
    if (y < -65535) return range_s16hi(0, clamp);
    if (y > 65536)  return range_s16lo(0, clamp);
    return clamp_s16(x-y, clamp);
}

static inline long s16g_mul(long x, long y, int clamp)
{
    if (x == 0) return 0;
    if (y > 32767) return (x>0)?range_s16hi(0, clamp):range_s16lo(0, clamp);
    return clamp_s16(x*y, clamp);
}

#define u16u16_add(x, y, clamp)   clamp_u16(x+y, clamp)
#define u16u16_sub(x, y, clamp)   clamp_u16((long)(x-y), clamp)
#define u16u16_mul(x, y, clamp)   clamp_u16(x*y, clamp)

static inline u_long u16g_add(u_long x, u_long y, int clamp)
{
    if (y > 65535)  return range_u16hi(0, clamp);
    return clamp_u16(x+y, clamp);
}

static inline u_long u16g_sub(u_long x, u_long y, int clamp)
{
    if (y > x)   return range_u16lo(0, clamp);
    return x-y;                 /* never overflows */
}

static inline u_long u16g_mul(u_long x, u_long y, int clamp)
{
    if (x == 0) return 0;
    if (y > 65535) return range_u16hi(0, clamp);
    return clamp_u16(x*y, clamp);
}

#if SIZEOF_LONG == 4
#define s32s32_add(x, y, clamp)  s32_add_safe(x, y, clamp)
#define s32s32_sub(x, y, clamp)  s32_sub_safe(x, y, clamp)
#define s32s32_mul(x, y, clamp)  s32_mul_safe(x, y, clamp)
#define s32g_add(x, y, clamp)    s32_add_safe(x, y, clamp)
#define s32g_sub(x, y, clamp)    s32_sub_safe(x, y, clamp)
#define s32g_mul(x, y, clamp)    s32_mul_safe(x, y, clamp)
#else  /* SIZEOF_LONG >= 8 */
#define s32s32_add(x, y, clamp)  clamp_s32(x+y, clamp)
#define s32s32_sub(x, y, clamp)  clamp_s32(x-y, clamp)
#define s32s32_mul(x, y, clamp)  clamp_s32(x*y, clamp)
#define s32g_add(x, y, clamp)    s32_add_safe(x, y, clamp)
#define s32g_sub(x, y, clamp)    s32_sub_safe(x, y, clamp)
#define s32g_mul(x, y, clamp)    s32_mul_safe(x, y, clamp)
#endif /* SIZEOF_LONG >= 8 */

static inline long s32_add_safe(long x, long y, int clamp)
{
    long r, v;
    SADDOV(r, v, x, y);
    if (v == 0) return clamp_s32(r, clamp);
    if (v > 0)  return range_s32hi(0, clamp);
    else        return range_s32lo(0, clamp);
}


static inline long s32_sub_safe(long x, long y, int clamp)
{
    long r, v;
    SSUBOV(r, v, x, y);
    if (v == 0) return clamp_s32(r, clamp);
    if (v > 0)  return range_s32hi(0, clamp);
    else        return range_s32lo(0, clamp);
}

static inline long s32_mul_safe(long x, long y, int clamp)
{
    long r, v;
    SMULOV(r, v, x, y);
    if (v == 0) return clamp_s32(r, clamp);
    if (v > 0)  return range_s32hi(0, clamp);
    else        return range_s32lo(0, clamp);
}

#if SIZEOF_LONG == 4
#define u32u32_add(x, y, clamp)  u32_add_safe(x, y, clamp)
#define u32u32_sub(x, y, clamp)  u32_sub_safe(x, y, clamp)
#define u32u32_mul(x, y, clamp)  u32_mul_safe(x, y, clamp)
#define u32g_add(x, y, clamp)    u32_add_safe(x, y, clamp)
#define u32g_sub(x, y, clamp)    u32_sub_safe(x, y, clamp)
#define u32g_mul(x, y, clamp)    u32_mul_safe(x, y, clamp)
#else  /* SIZEOF_LONG >= 8 */
#define u32u32_add(x, y, clamp)  clamp_u32(x+y, clamp)
#define u32u32_sub(x, y, clamp)  u32_sub_safe(x, y, clamp)
#define u32u32_mul(x, y, clamp)  clamp_u32(x*y, clamp)
#define u32g_add(x, y, clamp)    u32_add_safe(x, y, clamp)
#define u32g_sub(x, y, clamp)    u32_sub_safe(x, y, clamp)
#define u32g_mul(x, y, clamp)    u32_mul_safe(x, y, clamp)
#endif /* SIZEOF_LONG >= 8 */

static inline u_long u32_add_safe(u_long x, u_long y, int clamp)
{
    u_long r, v;
    UADDOV(r, v, x, y);
    if (v == 0) return clamp_u32(r, clamp);
    else        return range_u32hi(0, clamp);
}

static inline u_long u32_sub_safe(u_long x, u_long y, int clamp)
{
    u_long r, v;
    USUBOV(r, v, x, y);
    if (v == 0) return clamp_u32(r, clamp);
    else        return range_u32lo(0, clamp);
}

static inline u_long u32_mul_safe(u_long x, u_long y, int clamp)
{
    u_long r, v;
    UMULOV(r, v, x, y);
    if (v == 0) return clamp_u32(r, clamp);
    else        return range_u32hi(0, clamp);
}

#define s64s64_add(x, y, clamp)  s64g_add(x, y, clamp)
#define s64s64_sub(x, y, clamp)  s64g_sub(x, y, clamp)
#define s64s64_mul(x, y, clamp)  s64g_mul(x, y, clamp)

static inline int64_t s64g_add(int64_t x, int64_t y, int clamp)
{
#if SIZEOF_LONG == 4
    ScmObj xx = Scm_MakeInteger64(x);
    ScmObj yy = Scm_MakeInteger64(y);
    ScmObj r = Scm_Add(xx, yy);
    return Scm_GetInteger64Clamp(r, clamp, NULL);
#else
    long r, v;
    SADDOV(r, v, x, y);
    if (v == 0) return r;
    if (v > 0)  return range_s64hi(0, clamp);
    else        return range_s64lo(0, clamp);
#endif
}

static inline int64_t s64g_sub(int64_t x, int64_t y, int clamp)
{
#if SIZEOF_LONG == 4
    ScmObj xx = Scm_MakeInteger64(x);
    ScmObj yy = Scm_MakeInteger64(y);
    ScmObj r = Scm_Sub(xx, yy);
    return Scm_GetInteger64Clamp(r, clamp, NULL);
#else
    long r, v;
    SSUBOV(r, v, x, y);
    if (v == 0) return r;
    if (v > 0)  return range_s64hi(0, clamp);
    else        return range_s64lo(0, clamp);
#endif
}

static inline int64_t s64g_mul(int64_t x, int64_t y, int clamp)
{
#if SIZEOF_LONG == 4
    ScmObj xx = Scm_MakeInteger64(x);
    ScmObj yy = Scm_MakeInteger64(y);
    ScmObj r = Scm_Mul(xx, yy);
    return Scm_GetInteger64Clamp(r, clamp, NULL);
#else
    long r, v;
    SMULOV(r, v, x, y);
    if (v == 0) return r;
    if (v > 0)  return range_s64hi(0, clamp);
    else        return range_s64lo(0, clamp);
#endif
}

#define u64u64_add(x, y, clamp)  u64g_add(x, y, clamp)
#define u64u64_sub(x, y, clamp)  u64g_sub(x, y, clamp)
#define u64u64_mul(x, y, clamp)  u64g_mul(x, y, clamp)

static inline uint64_t u64g_add(uint64_t x, uint64_t y, int clamp)
{
#if SIZEOF_LONG == 4
    ScmObj xx = Scm_MakeIntegerU64(x);
    ScmObj yy = Scm_MakeIntegerU64(y);
    ScmObj r = Scm_Add(xx, yy);
    return Scm_GetIntegerU64Clamp(r, clamp, NULL);
#else
    u_long r, v;
    UADDOV(r, v, x, y);
    if (v == 0) return r;
    else        return range_u64hi(0, clamp);
#endif
}

static inline uint64_t u64g_sub(uint64_t x, uint64_t y, int clamp)
{
#if SIZEOF_LONG == 4
    ScmObj xx = Scm_MakeIntegerU64(x);
    ScmObj yy = Scm_MakeIntegerU64(y);
    ScmObj r = Scm_Sub(xx, yy);
    return Scm_GetIntegerU64Clamp(r, clamp, NULL);
#else
    u_long r, v;
    USUBOV(r, v, x, y);
    if (v == 0) return r;
    else        return range_u64lo(0, clamp);
#endif
}

static inline uint64_t u64g_mul(uint64_t x, uint64_t y, int clamp)
{
#if SIZEOF_LONG == 4
    ScmObj xx = Scm_MakeIntegerU64(x);
    ScmObj yy = Scm_MakeIntegerU64(y);
    ScmObj r = Scm_Mul(xx, yy);
    return Scm_GetIntegerU64Clamp(r, clamp, NULL);
#else
    u_long r, v;
    UMULOV(r, v, x, y);
    if (v == 0) return r;
    else        return range_u64hi(0, clamp);
#endif
}

#define f16f16_add(x, y, clamp)   (x+y)
#define f16f16_sub(x, y, clamp)   (x-y)
#define f16f16_mul(x, y, clamp)   (x*y)
#define f16f16_div(x, y, clamp)   (x/y)

#define f16g_add(x, y, clamp)     (x+y)
#define f16g_sub(x, y, clamp)     (x-y)
#define f16g_mul(x, y, clamp)     (x*y)
#define f16g_div(x, y, clamp)     (x/y)

#define f32f32_add(x, y, clamp)   (x+y)
#define f32f32_sub(x, y, clamp)   (x-y)
#define f32f32_mul(x, y, clamp)   (x*y)
#define f32f32_div(x, y, clamp)   (x/y)

#define f32g_add(x, y, clamp)   (x+y)
#define f32g_sub(x, y, clamp)   (x-y)
#define f32g_mul(x, y, clamp)   (x*y)
#define f32g_div(x, y, clamp)   (x/y)

#define f64f64_add(x, y, clamp)   (x+y)
#define f64f64_sub(x, y, clamp)   (x-y)
#define f64f64_mul(x, y, clamp)   (x*y)
#define f64f64_div(x, y, clamp)   (x/y)

#define f64g_add(x, y, clamp)   (x+y)
#define f64g_sub(x, y, clamp)   (x-y)
#define f64g_mul(x, y, clamp)   (x*y)
#define f64g_div(x, y, clamp)   (x/y)

static inline ScmDoubleComplex complex_half_to_double(ScmHalfComplex x)
{
    return (ScmDoubleComplex)(Scm_HalfToDouble(x.r)
                            + Scm_HalfToDouble(x.i) * _Complex_I);
}

static inline ScmHalfComplex complex_double_to_half(ScmDoubleComplex x)
{
    return (ScmHalfComplex){Scm_DoubleToHalf(creal(x)),
                            Scm_DoubleToHalf(cimag(x))};
}


static inline ScmHalfComplex c32c32_add(ScmHalfComplex x,
                                        ScmHalfComplex y,
                                        int clamp SCM_UNUSED)
{
    ScmDoubleComplex cx = complex_half_to_double(x);
    ScmDoubleComplex cy = complex_half_to_double(y);
    return complex_double_to_half(cx+cy);
}

static inline ScmHalfComplex c32c32_sub(ScmHalfComplex x,
                                        ScmHalfComplex y,
                                        int clamp SCM_UNUSED)
{
    ScmDoubleComplex cx = complex_half_to_double(x);
    ScmDoubleComplex cy = complex_half_to_double(y);
    return complex_double_to_half(cx-cy);
}

static inline ScmHalfComplex c32c32_mul(ScmHalfComplex x,
                                        ScmHalfComplex y,
                                        int clamp SCM_UNUSED)
{
    ScmDoubleComplex cx = complex_half_to_double(x);
    ScmDoubleComplex cy = complex_half_to_double(y);
    return complex_double_to_half(cx*cy);
}

static inline ScmHalfComplex c32c32_div(ScmHalfComplex x,
                                        ScmHalfComplex y,
                                        int clamp SCM_UNUSED)
{
    ScmDoubleComplex cx = complex_half_to_double(x);
    ScmDoubleComplex cy = complex_half_to_double(y);
    return complex_double_to_half(cx/cy);
}


#define c32g_add(x, y, clamp)   c32c32_add(x, y, clamp)
#define c32g_sub(x, y, clamp)   c32c32_sub(x, y, clamp)
#define c32g_mul(x, y, clamp)   c32c32_mul(x, y, clamp)
#define c32g_div(x, y, clamp)   c32c32_div(x, y, clamp)

#define c64c64_add(x, y, clamp) (x+y)
#define c64c64_sub(x, y, clamp) (x-y)
#define c64c64_mul(x, y, clamp) (x*y)
#define c64c64_div(x, y, clamp) (x/y)

#define c64g_add(x, y, clamp)   (x+y)
#define c64g_sub(x, y, clamp)   (x-y)
#define c64g_mul(x, y, clamp)   (x*y)
#define c64g_div(x, y, clamp)   (x/y)

#define c128c128_add(x, y, clamp) (x+y)
#define c128c128_sub(x, y, clamp) (x-y)
#define c128c128_mul(x, y, clamp) (x*y)
#define c128c128_div(x, y, clamp) (x/y)

#define c128g_add(x, y, clamp)   (x+y)
#define c128g_sub(x, y, clamp)   (x-y)
#define c128g_mul(x, y, clamp)   (x*y)
#define c128g_div(x, y, clamp)   (x/y)


/****** Number extraction *****/
/* like unbox, but not as strict.  sets *oor = TRUE if x is out of range. */

static inline long s8num(ScmObj x, int *oor)
{
    return Scm_GetIntegerClamp(x, SCM_CLAMP_NONE, oor);
}

#define s16num(x, oor)           s8num(x, oor)
#define s32num(x, oor)           s8num(x, oor)

static inline u_long u8num(ScmObj x, int *oor)
{
    return Scm_GetIntegerUClamp(x, SCM_CLAMP_NONE, oor);
}

#define u16num(x, oor)           u8num(x, oor)
#define u32num(x, oor)           u8num(x, oor)

static inline int64_t s64num(ScmObj x, int *oor)
{
    return Scm_GetInteger64Clamp(x, SCM_CLAMP_NONE, oor);
}

static inline uint64_t u64num(ScmObj x, int *oor)
{
    return Scm_GetIntegerU64Clamp(x, SCM_CLAMP_NONE, oor);
}

#define f16num(x, oor) ((*oor = FALSE), Scm_GetDouble(x))
#define f32num(x, oor) ((*oor = FALSE),((float)Scm_GetDouble(x)))
#define f64num(x, oor) ((*oor = FALSE), Scm_GetDouble(x))

#define c32num(x, oor) ((*oor = FALSE), Scm_GetHalfComplex(x))
#define c64num(x, oor) ((*oor = FALSE), Scm_GetFloatComplex(x))
#define c128num(x, oor) ((*oor = FALSE), Scm_GetDoubleComplex(x))

/****** Bit operation *****/

static inline u_long bitext(ScmObj x)
{
    if (SCM_INTP(x)) return (u_long)SCM_INT_VALUE(x);
    if (SCM_BIGNUMP(x)) {
        if (SCM_BIGNUM_SIGN(x) > 0) {
            return SCM_BIGNUM(x)->values[0];
        } else {
            return ~(SCM_BIGNUM(x)->values[0]) + 1;
        }
    }
    Scm_Error("integer required, but got %S", x);
    return 0;
}

static inline uint64_t bitext64(ScmObj x)
{
    uint64_t r = 0;
    if (SCM_INTP(x)) r = SCM_INT_VALUE(x);
    else if (SCM_BIGNUMP(x)) {
        ScmObj xx = Scm_LogAnd(x, SCM_2_64_MINUS_1);
        r = Scm_GetIntegerU64(xx);
    }
    else {
        Scm_Error("integer required, but got %S", x);
    }
    return r;
}

#define INT64BITOP(r, x, op, y)  (r = x op y)
/****** Multiply-and-add operation. *****/

static inline long s8muladd(long x, long y, long acc, ScmObj *sacc)
{
    long k, v, m;
    m = x * y;
    SADDOV(k, v, acc, m);
    if (v) {
        *sacc = Scm_Add(*sacc, Scm_MakeInteger(acc));
        return m;
    } else {
        return k;
    }
}

#define s16muladd(x, y, acc, sacc) s8muladd(x, y, acc, sacc)

static inline long s32muladd(long x, long y, long acc, ScmObj *sacc)
{
    long k, v, m;
    SMULOV(m, v, x, y);
    if (v) {
        *sacc = Scm_Add(*sacc, Scm_Mul(Scm_MakeInteger(x),
                                       Scm_MakeInteger(y)));
        return acc;
    } else {
        SADDOV(k, v, acc, m);
        if (v) {
            *sacc = Scm_Add(*sacc, Scm_MakeInteger(acc));
            return m;
        } else {
            return k;
        }
    }
}

#if SIZEOF_LONG == 4
static inline int64_t s64muladd(int64_t x, int64_t y, int64_t acc, ScmObj *sacc)
{
    /* we don't use acc, and operate only on sacc. */
    *sacc = Scm_Add(*sacc, Scm_Mul(Scm_MakeInteger64(x),
                                   Scm_MakeInteger64(y)));
    return acc;
}
#else
#define s64muladd(x, y, acc, sacc) s32muladd(x, y, acc, sacc)
#endif

static inline u_long u8muladd(u_long x, u_long y, u_long acc, ScmObj *sacc)
{
    u_long k, v, m;
    m = x * y;
    UADDOV(k, v, acc, m);
    if (v) {
        *sacc = Scm_Add(*sacc, Scm_MakeIntegerU(acc));
        return m;
    } else {
        return k;
    }
}

#define u16muladd(x, y, acc, sacc) u8muladd(x, y, acc, sacc)

static inline u_long u32muladd(u_long x, u_long y, u_long acc, ScmObj *sacc)
{
    u_long k, v, m;
    UMULOV(m, v, x, y);
    if (v) {
        *sacc = Scm_Add(*sacc, Scm_Mul(Scm_MakeIntegerU(x),
                                              Scm_MakeIntegerU(y)));
        return acc;
    } else {
        UADDOV(k, v, acc, m);
        if (v) {
            *sacc = Scm_Add(*sacc, Scm_MakeIntegerU(acc));
            return m;
        } else {
            return k;
        }
    }
}

#if SIZEOF_LONG == 4
static inline uint64_t u64muladd(uint64_t x, uint64_t y, uint64_t acc, ScmObj *sacc)
{
    /* we don't use acc, and operate only on sacc. */
    *sacc = Scm_Add(*sacc, Scm_Mul(Scm_MakeIntegerU64(x),
                                          Scm_MakeIntegerU64(y)));
    return acc;
}
#else
#define u64muladd(x, y, acc, sacc) u32muladd(x, y, acc, sacc)
#endif

#define f16muladd(x, y, acc, sacc)  (acc + x*y)
#define f32muladd(x, y, acc, sacc)  (acc + x*y)
#define f64muladd(x, y, acc, sacc)  (acc + x*y)

#define c32muladd(x, y, acc, sacc) \
    (ScmHalfComplex){acc.r + x.r*y.r - x.i*y.i, acc.i + x.i*y.r + x.r*y.i} 
#define c64muladd(x, y, acc, sacc)  (acc + x*y)
#define c128muladd(x, y, acc, sacc)  (acc + x*y)

#if SCM_EMULATE_INT64
#define INT64LT(a, b)  ((a.hi < b.hi) || (a.hi == b.hi) && (a.lo < b.lo))
#else
#define INT64LT(a, b)  (a < b)
#endif


static void f64vector_swapb_arm2le(ScmF64Vector *v)
{
    int len = SCM_UVECTOR_SIZE(v);
    double *d = SCM_F64VECTOR_ELEMENTS(v);
    for (int i=0; i<len; i++, d++) {
        swap_f64_t v;
        v.val = *d;
        SWAP_ARM2LE(v);
        *d = v.val;
    }
}

static void f64vector_swapb_arm2be(ScmF64Vector *v)
{
    int len = SCM_UVECTOR_SIZE(v);
    double *d = SCM_F64VECTOR_ELEMENTS(v);
    for (int i=0; i<len; i++, d++) {
        swap_f64_t v;
        v.val = *d;
        SWAP_ARM2BE(v);
        *d = v.val;
    }
}

ScmObj Scm_F64VectorSwapBytes_ARM2LE(ScmF64Vector *v)
{
    ScmObj d = Scm_F64VectorCopy(v, 0, -1);
    f64vector_swapb_arm2le(SCM_F64VECTOR(d));
    return d;
}

ScmObj Scm_F64VectorSwapBytesX_ARM2LE(ScmF64Vector *v)
{
    SCM_UVECTOR_CHECK_MUTABLE(v);
    f64vector_swapb_arm2le(v);
    return SCM_OBJ(v);
}

ScmObj Scm_F64VectorSwapBytes_ARM2BE(ScmF64Vector *v)
{
    ScmObj d = Scm_F64VectorCopy(v, 0, -1);
    f64vector_swapb_arm2be(SCM_F64VECTOR(d));
    return d;
}

ScmObj Scm_F64VectorSwapBytesX_ARM2BE(ScmF64Vector *v)
{
    SCM_UVECTOR_CHECK_MUTABLE(v);
    f64vector_swapb_arm2be(v);
    return SCM_OBJ(v);
}


/*---------------------------------------------------------------
 * S8Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToS8Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeS8Vector(size, 0);
    for (int i=0; i<size; i++) {
        int8_t elt;
        ScmObj obj = arr[i];
        elt = (int8_t)Scm_GetInteger8Clamp(obj, clamp, NULL);
        SCM_S8VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToS8Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToS8Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_S8VectorFill(ScmUVector *vec, int8_t fill, int start, int end)
{
    int size = SCM_S8VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_S8VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_S8VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_S8VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        int8_t elt = SCM_S8VECTOR_ELEMENTS(vec)[i];
        obj = SCM_MAKE_INT(elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_S8VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_S8VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        int8_t elt = SCM_S8VECTOR_ELEMENTS(vec)[i];
        obj = SCM_MAKE_INT(elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_S8VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_S8VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeS8VectorFromArray(end-start,
                                     SCM_S8VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_S8VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_S8VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_S8VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_S8VECTOR_ELEMENTS(dst) + dstart,
            SCM_S8VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(int8_t));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * U8Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToU8Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeU8Vector(size, 0);
    for (int i=0; i<size; i++) {
        uint8_t elt;
        ScmObj obj = arr[i];
        elt = (uint8_t)Scm_GetIntegerU8Clamp(obj, clamp, NULL);
        SCM_U8VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToU8Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToU8Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_U8VectorFill(ScmUVector *vec, uint8_t fill, int start, int end)
{
    int size = SCM_U8VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_U8VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_U8VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_U8VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        uint8_t elt = SCM_U8VECTOR_ELEMENTS(vec)[i];
        obj = SCM_MAKE_INT(elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_U8VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_U8VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        uint8_t elt = SCM_U8VECTOR_ELEMENTS(vec)[i];
        obj = SCM_MAKE_INT(elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_U8VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_U8VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeU8VectorFromArray(end-start,
                                     SCM_U8VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_U8VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_U8VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_U8VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_U8VECTOR_ELEMENTS(dst) + dstart,
            SCM_U8VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(uint8_t));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * S16Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToS16Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeS16Vector(size, 0);
    for (int i=0; i<size; i++) {
        int16_t elt;
        ScmObj obj = arr[i];
        elt = (int16_t)Scm_GetInteger16Clamp(obj, clamp, NULL);
        SCM_S16VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToS16Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToS16Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_S16VectorFill(ScmUVector *vec, int16_t fill, int start, int end)
{
    int size = SCM_S16VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_S16VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_S16VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_S16VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        int16_t elt = SCM_S16VECTOR_ELEMENTS(vec)[i];
        obj = SCM_MAKE_INT(elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_S16VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_S16VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        int16_t elt = SCM_S16VECTOR_ELEMENTS(vec)[i];
        obj = SCM_MAKE_INT(elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_S16VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_S16VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeS16VectorFromArray(end-start,
                                     SCM_S16VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_S16VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_S16VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_S16VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_S16VECTOR_ELEMENTS(dst) + dstart,
            SCM_S16VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(int16_t));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * U16Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToU16Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeU16Vector(size, 0);
    for (int i=0; i<size; i++) {
        uint16_t elt;
        ScmObj obj = arr[i];
        elt = (uint16_t)Scm_GetIntegerU16Clamp(obj, clamp, NULL);
        SCM_U16VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToU16Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToU16Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_U16VectorFill(ScmUVector *vec, uint16_t fill, int start, int end)
{
    int size = SCM_U16VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_U16VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_U16VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_U16VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        uint16_t elt = SCM_U16VECTOR_ELEMENTS(vec)[i];
        obj = SCM_MAKE_INT(elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_U16VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_U16VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        uint16_t elt = SCM_U16VECTOR_ELEMENTS(vec)[i];
        obj = SCM_MAKE_INT(elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_U16VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_U16VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeU16VectorFromArray(end-start,
                                     SCM_U16VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_U16VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_U16VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_U16VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_U16VECTOR_ELEMENTS(dst) + dstart,
            SCM_U16VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(uint16_t));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * S32Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToS32Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeS32Vector(size, 0);
    for (int i=0; i<size; i++) {
        int32_t elt;
        ScmObj obj = arr[i];
        elt = (int32_t)Scm_GetInteger32Clamp(obj, clamp, NULL);
        SCM_S32VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToS32Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToS32Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_S32VectorFill(ScmUVector *vec, int32_t fill, int start, int end)
{
    int size = SCM_S32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_S32VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_S32VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_S32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        int32_t elt = SCM_S32VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeInteger(elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_S32VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_S32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        int32_t elt = SCM_S32VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeInteger(elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_S32VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_S32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeS32VectorFromArray(end-start,
                                     SCM_S32VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_S32VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_S32VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_S32VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_S32VECTOR_ELEMENTS(dst) + dstart,
            SCM_S32VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(int32_t));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * U32Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToU32Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeU32Vector(size, 0);
    for (int i=0; i<size; i++) {
        uint32_t elt;
        ScmObj obj = arr[i];
        elt = (uint32_t)Scm_GetIntegerU32Clamp(obj, clamp, NULL);
        SCM_U32VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToU32Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToU32Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_U32VectorFill(ScmUVector *vec, uint32_t fill, int start, int end)
{
    int size = SCM_U32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_U32VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_U32VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_U32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        uint32_t elt = SCM_U32VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeIntegerU(elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_U32VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_U32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        uint32_t elt = SCM_U32VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeIntegerU(elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_U32VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_U32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeU32VectorFromArray(end-start,
                                     SCM_U32VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_U32VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_U32VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_U32VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_U32VECTOR_ELEMENTS(dst) + dstart,
            SCM_U32VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(uint32_t));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * S64Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToS64Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeS64Vector(size, 0);
    for (int i=0; i<size; i++) {
        int64_t elt;
        ScmObj obj = arr[i];
        elt = Scm_GetInteger64Clamp(obj, clamp, NULL);
        SCM_S64VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToS64Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToS64Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_S64VectorFill(ScmUVector *vec, int64_t fill, int start, int end)
{
    int size = SCM_S64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_S64VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_S64VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_S64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        int64_t elt = SCM_S64VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeInteger64(elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_S64VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_S64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        int64_t elt = SCM_S64VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeInteger64(elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_S64VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_S64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeS64VectorFromArray(end-start,
                                     SCM_S64VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_S64VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_S64VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_S64VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_S64VECTOR_ELEMENTS(dst) + dstart,
            SCM_S64VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(int64_t));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * U64Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToU64Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeU64Vector(size, 0);
    for (int i=0; i<size; i++) {
        uint64_t elt;
        ScmObj obj = arr[i];
        elt = Scm_GetIntegerU64Clamp(obj, clamp, NULL);
        SCM_U64VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToU64Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToU64Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_U64VectorFill(ScmUVector *vec, uint64_t fill, int start, int end)
{
    int size = SCM_U64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_U64VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_U64VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_U64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        uint64_t elt = SCM_U64VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeIntegerU64(elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_U64VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_U64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        uint64_t elt = SCM_U64VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeIntegerU64(elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_U64VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_U64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeU64VectorFromArray(end-start,
                                     SCM_U64VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_U64VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_U64VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_U64VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_U64VECTOR_ELEMENTS(dst) + dstart,
            SCM_U64VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(uint64_t));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * F16Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToF16Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeF16Vector(size, 0);
    for (int i=0; i<size; i++) {
        ScmHalfFloat elt;
        ScmObj obj = arr[i];
        elt = Scm_DoubleToHalf(Scm_GetDouble(obj));
        SCM_F16VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToF16Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToF16Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_F16VectorFill(ScmUVector *vec, ScmHalfFloat fill, int start, int end)
{
    int size = SCM_F16VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_F16VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_F16VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_F16VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        ScmHalfFloat elt = SCM_F16VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeFlonum(Scm_HalfToDouble(elt));
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_F16VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_F16VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        ScmHalfFloat elt = SCM_F16VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeFlonum(Scm_HalfToDouble(elt));
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_F16VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_F16VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeF16VectorFromArray(end-start,
                                     SCM_F16VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_F16VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_F16VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_F16VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_F16VECTOR_ELEMENTS(dst) + dstart,
            SCM_F16VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(ScmHalfFloat));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * F32Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToF32Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeF32Vector(size, 0);
    for (int i=0; i<size; i++) {
        float elt;
        ScmObj obj = arr[i];
        elt = (float)Scm_GetDouble(obj);
        SCM_F32VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToF32Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToF32Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_F32VectorFill(ScmUVector *vec, float fill, int start, int end)
{
    int size = SCM_F32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_F32VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_F32VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_F32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        float elt = SCM_F32VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeFlonum((double)elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_F32VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_F32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        float elt = SCM_F32VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeFlonum((double)elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_F32VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_F32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeF32VectorFromArray(end-start,
                                     SCM_F32VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_F32VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_F32VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_F32VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_F32VECTOR_ELEMENTS(dst) + dstart,
            SCM_F32VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(float));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * F64Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToF64Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeF64Vector(size, 0);
    for (int i=0; i<size; i++) {
        double elt;
        ScmObj obj = arr[i];
        elt = Scm_GetDouble(obj);
        SCM_F64VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToF64Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToF64Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_F64VectorFill(ScmUVector *vec, double fill, int start, int end)
{
    int size = SCM_F64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_F64VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_F64VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_F64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        double elt = SCM_F64VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeFlonum(elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_F64VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_F64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        double elt = SCM_F64VECTOR_ELEMENTS(vec)[i];
        obj = Scm_MakeFlonum(elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_F64VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_F64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeF64VectorFromArray(end-start,
                                     SCM_F64VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_F64VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_F64VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_F64VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_F64VECTOR_ELEMENTS(dst) + dstart,
            SCM_F64VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(double));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * C32Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToC32Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeC32Vector(size, (ScmHalfComplex){0, 0});
    for (int i=0; i<size; i++) {
        ScmHalfComplex elt;
        ScmObj obj = arr[i];
        elt = Scm_GetHalfComplex(obj);
        SCM_C32VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToC32Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToC32Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_C32VectorFill(ScmUVector *vec, ScmHalfComplex fill, int start, int end)
{
    int size = SCM_C32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_C32VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_C32VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_C32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        ScmHalfComplex elt = SCM_C32VECTOR_ELEMENTS(vec)[i];
        obj = Scm_HalfComplexToComplex(elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_C32VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_C32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        ScmHalfComplex elt = SCM_C32VECTOR_ELEMENTS(vec)[i];
        obj = Scm_HalfComplexToComplex(elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_C32VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_C32VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeC32VectorFromArray(end-start,
                                     SCM_C32VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_C32VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_C32VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_C32VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_C32VECTOR_ELEMENTS(dst) + dstart,
            SCM_C32VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(ScmHalfComplex));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * C64Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToC64Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeC64Vector(size, 0);
    for (int i=0; i<size; i++) {
        ScmFloatComplex elt;
        ScmObj obj = arr[i];
        elt = Scm_GetFloatComplex(obj);
        SCM_C64VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToC64Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToC64Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_C64VectorFill(ScmUVector *vec, ScmFloatComplex fill, int start, int end)
{
    int size = SCM_C64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_C64VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_C64VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_C64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        ScmFloatComplex elt = SCM_C64VECTOR_ELEMENTS(vec)[i];
        obj = Scm_FloatComplexToComplex(elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_C64VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_C64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        ScmFloatComplex elt = SCM_C64VECTOR_ELEMENTS(vec)[i];
        obj = Scm_FloatComplexToComplex(elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_C64VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_C64VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeC64VectorFromArray(end-start,
                                     SCM_C64VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_C64VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_C64VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_C64VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_C64VECTOR_ELEMENTS(dst) + dstart,
            SCM_C64VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(ScmFloatComplex));
    return SCM_OBJ(dst);
}


/*---------------------------------------------------------------
 * C128Vector
 */

/*
 * Class stuff
 */

/*
 * Converters
 */

ScmObj Scm_ObjArrayToC128Vector(ScmObj *arr, int size, int clamp SCM_UNUSED)
{
    ScmUVector *vec = (ScmUVector*)Scm_MakeC128Vector(size, 0);
    for (int i=0; i<size; i++) {
        ScmDoubleComplex elt;
        ScmObj obj = arr[i];
        elt = Scm_GetDoubleComplex(obj);
        SCM_C128VECTOR_ELEMENTS(vec)[i] = elt;
    }
    return SCM_OBJ(vec);
}

ScmObj Scm_VectorToC128Vector(ScmVector *ivec, int start, int end, int clamp)
{
    int length = SCM_VECTOR_SIZE(ivec);
    SCM_CHECK_START_END(start, end, length);
    return Scm_ObjArrayToC128Vector(SCM_VECTOR_ELEMENTS(ivec)+start,
                                    end-start, clamp);
}

/*
 * Accessors and modifiers
 */

ScmObj Scm_C128VectorFill(ScmUVector *vec, ScmDoubleComplex fill, int start, int end)
{
    int size = SCM_C128VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    SCM_UVECTOR_CHECK_MUTABLE(vec);
    for (int i=start; i<end; i++) SCM_C128VECTOR_ELEMENTS(vec)[i] = fill;
    return SCM_OBJ(vec);
}

ScmObj Scm_C128VectorToList(ScmUVector *vec, int start, int end)
{
    ScmObj head = SCM_NIL, tail = SCM_NIL;
    int size = SCM_C128VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        ScmDoubleComplex elt = SCM_C128VECTOR_ELEMENTS(vec)[i];
        obj = Scm_DoubleComplexToComplex(elt);
        SCM_APPEND1(head, tail, obj);
    }
    return head;
}

ScmObj Scm_C128VectorToVector(ScmUVector *vec, int start, int end)
{
    int size = SCM_C128VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    ScmObj ovec = Scm_MakeVector(end-start, SCM_UNDEFINED);
    for (int i=start; i<end; i++) {
        ScmObj obj;
        ScmDoubleComplex elt = SCM_C128VECTOR_ELEMENTS(vec)[i];
        obj = Scm_DoubleComplexToComplex(elt);
        SCM_VECTOR_ELEMENT(ovec, i-start) = obj;
    }
    return ovec;
}

ScmObj Scm_C128VectorCopy(ScmUVector *vec, ScmSmallInt start, ScmSmallInt end)
{
    ScmSmallInt size = SCM_C128VECTOR_SIZE(vec);
    SCM_CHECK_START_END(start, end, size);
    return Scm_MakeC128VectorFromArray(end-start,
                                     SCM_C128VECTOR_ELEMENTS(vec)+start);
}

ScmObj Scm_C128VectorCopyX(ScmUVector *dst,
                           ScmSmallInt dstart,
                           ScmUVector *src,
                           ScmSmallInt sstart,
                           ScmSmallInt send)
{
    ScmSmallInt dlen = SCM_C128VECTOR_SIZE(dst);
    ScmSmallInt slen = SCM_C128VECTOR_SIZE(src);
    ScmSmallInt size;

    SCM_UVECTOR_CHECK_MUTABLE(dst);
    SCM_CHECK_START_END(sstart, send, slen);

    if (dstart < 0 || dstart >= dlen) return SCM_OBJ(dst);
    if (dlen - dstart > send - sstart)  size = send - sstart;
    else size = dlen - dstart;

    memmove(SCM_C128VECTOR_ELEMENTS(dst) + dstart,
            SCM_C128VECTOR_ELEMENTS(src) + sstart,
            size * sizeof(ScmDoubleComplex));
    return SCM_OBJ(dst);
}

/* NB: s1 can be a register flonum. */
static void s8vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_S8VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S8VECTOR_ELEMENTS(s1)[i];
            r = s8s8_add(v0, v1, clamp);
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = s8num(vv1, &oor);
            if (!oor) {
                r = s8g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetInteger8Clamp(rr, clamp, NULL);
            }
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = s8num(vv1, &oor);
            if (!oor) {
                r = s8g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetInteger8Clamp(rr, clamp, NULL);
            }
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = s8num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = s8g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetInteger8Clamp(rr, clamp, NULL);
            }
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
    }
}

ScmObj Scm_S8VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S8VECTOR,
                               SCM_S8VECTOR_SIZE(s0),
                               NULL);
    s8vector_add("s8vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_S8VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    s8vector_add("s8vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void u8vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_U8VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_U8VECTOR_ELEMENTS(s1)[i];
            r = u8u8_add(v0, v1, clamp);
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = u8num(vv1, &oor);
            if (!oor) {
                r = u8g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetIntegerU8Clamp(rr, clamp, NULL);
            }
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = u8num(vv1, &oor);
            if (!oor) {
                r = u8g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetIntegerU8Clamp(rr, clamp, NULL);
            }
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = u8num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = u8g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetIntegerU8Clamp(rr, clamp, NULL);
            }
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
    }
}

ScmObj Scm_U8VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U8VECTOR,
                               SCM_U8VECTOR_SIZE(s0),
                               NULL);
    u8vector_add("u8vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_U8VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    u8vector_add("u8vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void s16vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_S16VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S16VECTOR_ELEMENTS(s1)[i];
            r = s16s16_add(v0, v1, clamp);
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = s16num(vv1, &oor);
            if (!oor) {
                r = s16g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetInteger16Clamp(rr, clamp, NULL);
            }
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = s16num(vv1, &oor);
            if (!oor) {
                r = s16g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetInteger16Clamp(rr, clamp, NULL);
            }
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = s16num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = s16g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetInteger16Clamp(rr, clamp, NULL);
            }
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
    }
}

ScmObj Scm_S16VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S16VECTOR,
                               SCM_S16VECTOR_SIZE(s0),
                               NULL);
    s16vector_add("s16vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_S16VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    s16vector_add("s16vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void u16vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_U16VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_U16VECTOR_ELEMENTS(s1)[i];
            r = u16u16_add(v0, v1, clamp);
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = u16num(vv1, &oor);
            if (!oor) {
                r = u16g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetIntegerU16Clamp(rr, clamp, NULL);
            }
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = u16num(vv1, &oor);
            if (!oor) {
                r = u16g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetIntegerU16Clamp(rr, clamp, NULL);
            }
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = u16num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = u16g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetIntegerU16Clamp(rr, clamp, NULL);
            }
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
    }
}

ScmObj Scm_U16VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U16VECTOR,
                               SCM_U16VECTOR_SIZE(s0),
                               NULL);
    u16vector_add("u16vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_U16VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    u16vector_add("u16vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void s32vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_S32VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S32VECTOR_ELEMENTS(s1)[i];
            r = s32s32_add(v0, v1, clamp);
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = s32num(vv1, &oor);
            if (!oor) {
                r = s32g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetInteger32Clamp(rr, clamp, NULL);
            }
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = s32num(vv1, &oor);
            if (!oor) {
                r = s32g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetInteger32Clamp(rr, clamp, NULL);
            }
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = s32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = s32g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetInteger32Clamp(rr, clamp, NULL);
            }
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
    }
}

ScmObj Scm_S32VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S32VECTOR,
                               SCM_S32VECTOR_SIZE(s0),
                               NULL);
    s32vector_add("s32vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_S32VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    s32vector_add("s32vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void u32vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_U32VECTOR_SIZE(d), oor;
    u_long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            v1 = (u_long)SCM_U32VECTOR_ELEMENTS(s1)[i];
            r = u32u32_add(v0, v1, clamp);
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = u32num(vv1, &oor);
            if (!oor) {
                r = u32g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetIntegerU32Clamp(rr, clamp, NULL);
            }
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = u32num(vv1, &oor);
            if (!oor) {
                r = u32g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetIntegerU32Clamp(rr, clamp, NULL);
            }
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = u32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = u32g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetIntegerU32Clamp(rr, clamp, NULL);
            }
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
    }
}

ScmObj Scm_U32VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U32VECTOR,
                               SCM_U32VECTOR_SIZE(s0),
                               NULL);
    u32vector_add("u32vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_U32VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    u32vector_add("u32vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void s64vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_S64VECTOR_SIZE(d), oor;
    int64_t r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_S64VECTOR_ELEMENTS(s1)[i];
            r = s64s64_add(v0, v1, clamp);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = s64num(vv1, &oor);
            if (!oor) {
                r = s64g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger64(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetInteger64Clamp(rr, clamp, NULL);
            }
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = s64num(vv1, &oor);
            if (!oor) {
                r = s64g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger64(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetInteger64Clamp(rr, clamp, NULL);
            }
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = s64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = s64g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger64(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetInteger64Clamp(rr, clamp, NULL);
            }
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_S64VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S64VECTOR,
                               SCM_S64VECTOR_SIZE(s0),
                               NULL);
    s64vector_add("s64vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_S64VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    s64vector_add("s64vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void u64vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_U64VECTOR_SIZE(d), oor;
    uint64_t r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_U64VECTOR_ELEMENTS(s1)[i];
            r = u64u64_add(v0, v1, clamp);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = u64num(vv1, &oor);
            if (!oor) {
                r = u64g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU64(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetIntegerU64Clamp(rr, clamp, NULL);
            }
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = u64num(vv1, &oor);
            if (!oor) {
                r = u64g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU64(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetIntegerU64Clamp(rr, clamp, NULL);
            }
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = u64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = u64g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU64(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetIntegerU64Clamp(rr, clamp, NULL);
            }
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_U64VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U64VECTOR,
                               SCM_U64VECTOR_SIZE(s0),
                               NULL);
    u64vector_add("u64vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_U64VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    u64vector_add("u64vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void f16vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_F16VECTOR_SIZE(d), oor;
    double r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            v1 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s1)[i]);
            r = f16f16_add(v0, v1, clamp);
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = f16num(vv1, &oor);
            if (!oor) {
                r = f16g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = f16num(vv1, &oor);
            if (!oor) {
                r = f16g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = f16num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            if (!oor) {
                r = f16g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetDouble(rr);
            }
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
    }
}

ScmObj Scm_F16VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_F16VECTOR,
                               SCM_F16VECTOR_SIZE(s0),
                               NULL);
    f16vector_add("f16vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_F16VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    f16vector_add("f16vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void f32vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_F32VECTOR_SIZE(d), oor;
    double r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            v1 = (double)SCM_F32VECTOR_ELEMENTS(s1)[i];
            r = f32f32_add(v0, v1, clamp);
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = f32num(vv1, &oor);
            if (!oor) {
                r = f32g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = f32num(vv1, &oor);
            if (!oor) {
                r = f32g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = f32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = f32g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetDouble(rr);
            }
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
    }
}

ScmObj Scm_F32VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_F32VECTOR,
                               SCM_F32VECTOR_SIZE(s0),
                               NULL);
    f32vector_add("f32vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_F32VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    f32vector_add("f32vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void f64vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_F64VECTOR_SIZE(d), oor;
    double r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_F64VECTOR_ELEMENTS(s1)[i];
            r = f64f64_add(v0, v1, clamp);
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = f64num(vv1, &oor);
            if (!oor) {
                r = f64g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = f64num(vv1, &oor);
            if (!oor) {
                r = f64g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = f64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = f64g_add(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetDouble(rr);
            }
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_F64VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_F64VECTOR,
                               SCM_F64VECTOR_SIZE(s0),
                               NULL);
    f64vector_add("f64vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_F64VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    f64vector_add("f64vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void c32vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_C32VECTOR_SIZE(d), oor;
    ScmHalfComplex r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_C32VECTOR_ELEMENTS(s1)[i];
            r = c32c32_add(v0, v1, clamp);
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = c32num(vv1, &oor);
            if (!oor) {
                r = c32g_add(v0, v1, clamp);
            } else {
                rr = Scm_HalfComplexToComplex(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetHalfComplex(rr);
            }
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = c32num(vv1, &oor);
            if (!oor) {
                r = c32g_add(v0, v1, clamp);
            } else {
                rr = Scm_HalfComplexToComplex(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetHalfComplex(rr);
            }
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = c32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = c32g_add(v0, v1, clamp);
            } else {
                rr = Scm_HalfComplexToComplex(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetHalfComplex(rr);
            }
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_C32VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_C32VECTOR,
                               SCM_C32VECTOR_SIZE(s0),
                               NULL);
    c32vector_add("c32vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_C32VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    c32vector_add("c32vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void c64vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_C64VECTOR_SIZE(d), oor;
    ScmFloatComplex r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_C64VECTOR_ELEMENTS(s1)[i];
            r = c64c64_add(v0, v1, clamp);
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = c64num(vv1, &oor);
            if (!oor) {
                r = c64g_add(v0, v1, clamp);
            } else {
                rr = Scm_FloatComplexToComplex(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetFloatComplex(rr);
            }
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = c64num(vv1, &oor);
            if (!oor) {
                r = c64g_add(v0, v1, clamp);
            } else {
                rr = Scm_FloatComplexToComplex(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetFloatComplex(rr);
            }
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = c64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = c64g_add(v0, v1, clamp);
            } else {
                rr = Scm_FloatComplexToComplex(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetFloatComplex(rr);
            }
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_C64VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_C64VECTOR,
                               SCM_C64VECTOR_SIZE(s0),
                               NULL);
    c64vector_add("c64vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_C64VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    c64vector_add("c64vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void c128vector_add(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_C128VECTOR_SIZE(d), oor;
    ScmDoubleComplex r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_C128VECTOR_ELEMENTS(s1)[i];
            r = c128c128_add(v0, v1, clamp);
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = c128num(vv1, &oor);
            if (!oor) {
                r = c128g_add(v0, v1, clamp);
            } else {
                rr = Scm_DoubleComplexToComplex(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetDoubleComplex(rr);
            }
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = c128num(vv1, &oor);
            if (!oor) {
                r = c128g_add(v0, v1, clamp);
            } else {
                rr = Scm_DoubleComplexToComplex(v0);
                rr = Scm_Add(rr, vv1);
                r = Scm_GetDoubleComplex(rr);
            }
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = c128num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = c128g_add(v0, v1, clamp);
            } else {
                rr = Scm_DoubleComplexToComplex(v0);
                rr = Scm_Add(rr, s1);
                r = Scm_GetDoubleComplex(rr);
            }
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_C128VectorAdd(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_C128VECTOR,
                               SCM_C128VECTOR_SIZE(s0),
                               NULL);
    c128vector_add("c128vector-add", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_C128VectorAddX(ScmUVector *s0, ScmObj s1, int clamp)
{
    c128vector_add("c128vector-add!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void s8vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_S8VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S8VECTOR_ELEMENTS(s1)[i];
            r = s8s8_sub(v0, v1, clamp);
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = s8num(vv1, &oor);
            if (!oor) {
                r = s8g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetInteger8Clamp(rr, clamp, NULL);
            }
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = s8num(vv1, &oor);
            if (!oor) {
                r = s8g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetInteger8Clamp(rr, clamp, NULL);
            }
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = s8num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = s8g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetInteger8Clamp(rr, clamp, NULL);
            }
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
    }
}

ScmObj Scm_S8VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S8VECTOR,
                               SCM_S8VECTOR_SIZE(s0),
                               NULL);
    s8vector_sub("s8vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_S8VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    s8vector_sub("s8vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void u8vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_U8VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_U8VECTOR_ELEMENTS(s1)[i];
            r = u8u8_sub(v0, v1, clamp);
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = u8num(vv1, &oor);
            if (!oor) {
                r = u8g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetIntegerU8Clamp(rr, clamp, NULL);
            }
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = u8num(vv1, &oor);
            if (!oor) {
                r = u8g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetIntegerU8Clamp(rr, clamp, NULL);
            }
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = u8num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = u8g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetIntegerU8Clamp(rr, clamp, NULL);
            }
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
    }
}

ScmObj Scm_U8VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U8VECTOR,
                               SCM_U8VECTOR_SIZE(s0),
                               NULL);
    u8vector_sub("u8vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_U8VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    u8vector_sub("u8vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void s16vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_S16VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S16VECTOR_ELEMENTS(s1)[i];
            r = s16s16_sub(v0, v1, clamp);
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = s16num(vv1, &oor);
            if (!oor) {
                r = s16g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetInteger16Clamp(rr, clamp, NULL);
            }
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = s16num(vv1, &oor);
            if (!oor) {
                r = s16g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetInteger16Clamp(rr, clamp, NULL);
            }
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = s16num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = s16g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetInteger16Clamp(rr, clamp, NULL);
            }
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
    }
}

ScmObj Scm_S16VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S16VECTOR,
                               SCM_S16VECTOR_SIZE(s0),
                               NULL);
    s16vector_sub("s16vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_S16VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    s16vector_sub("s16vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void u16vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_U16VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_U16VECTOR_ELEMENTS(s1)[i];
            r = u16u16_sub(v0, v1, clamp);
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = u16num(vv1, &oor);
            if (!oor) {
                r = u16g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetIntegerU16Clamp(rr, clamp, NULL);
            }
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = u16num(vv1, &oor);
            if (!oor) {
                r = u16g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetIntegerU16Clamp(rr, clamp, NULL);
            }
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = u16num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = u16g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetIntegerU16Clamp(rr, clamp, NULL);
            }
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
    }
}

ScmObj Scm_U16VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U16VECTOR,
                               SCM_U16VECTOR_SIZE(s0),
                               NULL);
    u16vector_sub("u16vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_U16VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    u16vector_sub("u16vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void s32vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_S32VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S32VECTOR_ELEMENTS(s1)[i];
            r = s32s32_sub(v0, v1, clamp);
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = s32num(vv1, &oor);
            if (!oor) {
                r = s32g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetInteger32Clamp(rr, clamp, NULL);
            }
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = s32num(vv1, &oor);
            if (!oor) {
                r = s32g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetInteger32Clamp(rr, clamp, NULL);
            }
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = s32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = s32g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetInteger32Clamp(rr, clamp, NULL);
            }
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
    }
}

ScmObj Scm_S32VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S32VECTOR,
                               SCM_S32VECTOR_SIZE(s0),
                               NULL);
    s32vector_sub("s32vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_S32VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    s32vector_sub("s32vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void u32vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_U32VECTOR_SIZE(d), oor;
    u_long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            v1 = (u_long)SCM_U32VECTOR_ELEMENTS(s1)[i];
            r = u32u32_sub(v0, v1, clamp);
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = u32num(vv1, &oor);
            if (!oor) {
                r = u32g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetIntegerU32Clamp(rr, clamp, NULL);
            }
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = u32num(vv1, &oor);
            if (!oor) {
                r = u32g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetIntegerU32Clamp(rr, clamp, NULL);
            }
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = u32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = u32g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetIntegerU32Clamp(rr, clamp, NULL);
            }
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
    }
}

ScmObj Scm_U32VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U32VECTOR,
                               SCM_U32VECTOR_SIZE(s0),
                               NULL);
    u32vector_sub("u32vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_U32VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    u32vector_sub("u32vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void s64vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_S64VECTOR_SIZE(d), oor;
    int64_t r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_S64VECTOR_ELEMENTS(s1)[i];
            r = s64s64_sub(v0, v1, clamp);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = s64num(vv1, &oor);
            if (!oor) {
                r = s64g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger64(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetInteger64Clamp(rr, clamp, NULL);
            }
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = s64num(vv1, &oor);
            if (!oor) {
                r = s64g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger64(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetInteger64Clamp(rr, clamp, NULL);
            }
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = s64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = s64g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger64(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetInteger64Clamp(rr, clamp, NULL);
            }
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_S64VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S64VECTOR,
                               SCM_S64VECTOR_SIZE(s0),
                               NULL);
    s64vector_sub("s64vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_S64VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    s64vector_sub("s64vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void u64vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_U64VECTOR_SIZE(d), oor;
    uint64_t r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_U64VECTOR_ELEMENTS(s1)[i];
            r = u64u64_sub(v0, v1, clamp);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = u64num(vv1, &oor);
            if (!oor) {
                r = u64g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU64(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetIntegerU64Clamp(rr, clamp, NULL);
            }
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = u64num(vv1, &oor);
            if (!oor) {
                r = u64g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU64(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetIntegerU64Clamp(rr, clamp, NULL);
            }
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = u64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = u64g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU64(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetIntegerU64Clamp(rr, clamp, NULL);
            }
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_U64VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U64VECTOR,
                               SCM_U64VECTOR_SIZE(s0),
                               NULL);
    u64vector_sub("u64vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_U64VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    u64vector_sub("u64vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void f16vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_F16VECTOR_SIZE(d), oor;
    double r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            v1 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s1)[i]);
            r = f16f16_sub(v0, v1, clamp);
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = f16num(vv1, &oor);
            if (!oor) {
                r = f16g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = f16num(vv1, &oor);
            if (!oor) {
                r = f16g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = f16num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            if (!oor) {
                r = f16g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetDouble(rr);
            }
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
    }
}

ScmObj Scm_F16VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_F16VECTOR,
                               SCM_F16VECTOR_SIZE(s0),
                               NULL);
    f16vector_sub("f16vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_F16VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    f16vector_sub("f16vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void f32vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_F32VECTOR_SIZE(d), oor;
    double r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            v1 = (double)SCM_F32VECTOR_ELEMENTS(s1)[i];
            r = f32f32_sub(v0, v1, clamp);
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = f32num(vv1, &oor);
            if (!oor) {
                r = f32g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = f32num(vv1, &oor);
            if (!oor) {
                r = f32g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = f32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = f32g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetDouble(rr);
            }
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
    }
}

ScmObj Scm_F32VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_F32VECTOR,
                               SCM_F32VECTOR_SIZE(s0),
                               NULL);
    f32vector_sub("f32vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_F32VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    f32vector_sub("f32vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void f64vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_F64VECTOR_SIZE(d), oor;
    double r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_F64VECTOR_ELEMENTS(s1)[i];
            r = f64f64_sub(v0, v1, clamp);
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = f64num(vv1, &oor);
            if (!oor) {
                r = f64g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = f64num(vv1, &oor);
            if (!oor) {
                r = f64g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = f64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = f64g_sub(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetDouble(rr);
            }
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_F64VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_F64VECTOR,
                               SCM_F64VECTOR_SIZE(s0),
                               NULL);
    f64vector_sub("f64vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_F64VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    f64vector_sub("f64vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void c32vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_C32VECTOR_SIZE(d), oor;
    ScmHalfComplex r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_C32VECTOR_ELEMENTS(s1)[i];
            r = c32c32_sub(v0, v1, clamp);
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = c32num(vv1, &oor);
            if (!oor) {
                r = c32g_sub(v0, v1, clamp);
            } else {
                rr = Scm_HalfComplexToComplex(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetHalfComplex(rr);
            }
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = c32num(vv1, &oor);
            if (!oor) {
                r = c32g_sub(v0, v1, clamp);
            } else {
                rr = Scm_HalfComplexToComplex(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetHalfComplex(rr);
            }
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = c32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = c32g_sub(v0, v1, clamp);
            } else {
                rr = Scm_HalfComplexToComplex(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetHalfComplex(rr);
            }
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_C32VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_C32VECTOR,
                               SCM_C32VECTOR_SIZE(s0),
                               NULL);
    c32vector_sub("c32vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_C32VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    c32vector_sub("c32vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void c64vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_C64VECTOR_SIZE(d), oor;
    ScmFloatComplex r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_C64VECTOR_ELEMENTS(s1)[i];
            r = c64c64_sub(v0, v1, clamp);
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = c64num(vv1, &oor);
            if (!oor) {
                r = c64g_sub(v0, v1, clamp);
            } else {
                rr = Scm_FloatComplexToComplex(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetFloatComplex(rr);
            }
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = c64num(vv1, &oor);
            if (!oor) {
                r = c64g_sub(v0, v1, clamp);
            } else {
                rr = Scm_FloatComplexToComplex(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetFloatComplex(rr);
            }
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = c64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = c64g_sub(v0, v1, clamp);
            } else {
                rr = Scm_FloatComplexToComplex(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetFloatComplex(rr);
            }
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_C64VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_C64VECTOR,
                               SCM_C64VECTOR_SIZE(s0),
                               NULL);
    c64vector_sub("c64vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_C64VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    c64vector_sub("c64vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void c128vector_sub(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_C128VECTOR_SIZE(d), oor;
    ScmDoubleComplex r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_C128VECTOR_ELEMENTS(s1)[i];
            r = c128c128_sub(v0, v1, clamp);
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = c128num(vv1, &oor);
            if (!oor) {
                r = c128g_sub(v0, v1, clamp);
            } else {
                rr = Scm_DoubleComplexToComplex(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetDoubleComplex(rr);
            }
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = c128num(vv1, &oor);
            if (!oor) {
                r = c128g_sub(v0, v1, clamp);
            } else {
                rr = Scm_DoubleComplexToComplex(v0);
                rr = Scm_Sub(rr, vv1);
                r = Scm_GetDoubleComplex(rr);
            }
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = c128num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = c128g_sub(v0, v1, clamp);
            } else {
                rr = Scm_DoubleComplexToComplex(v0);
                rr = Scm_Sub(rr, s1);
                r = Scm_GetDoubleComplex(rr);
            }
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_C128VectorSub(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_C128VECTOR,
                               SCM_C128VECTOR_SIZE(s0),
                               NULL);
    c128vector_sub("c128vector-sub", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_C128VectorSubX(ScmUVector *s0, ScmObj s1, int clamp)
{
    c128vector_sub("c128vector-sub!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void s8vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_S8VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S8VECTOR_ELEMENTS(s1)[i];
            r = s8s8_mul(v0, v1, clamp);
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = s8num(vv1, &oor);
            if (!oor) {
                r = s8g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetInteger8Clamp(rr, clamp, NULL);
            }
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = s8num(vv1, &oor);
            if (!oor) {
                r = s8g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetInteger8Clamp(rr, clamp, NULL);
            }
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = s8num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = s8g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetInteger8Clamp(rr, clamp, NULL);
            }
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
    }
}

ScmObj Scm_S8VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S8VECTOR,
                               SCM_S8VECTOR_SIZE(s0),
                               NULL);
    s8vector_mul("s8vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_S8VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    s8vector_mul("s8vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void u8vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_U8VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_U8VECTOR_ELEMENTS(s1)[i];
            r = u8u8_mul(v0, v1, clamp);
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = u8num(vv1, &oor);
            if (!oor) {
                r = u8g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetIntegerU8Clamp(rr, clamp, NULL);
            }
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = u8num(vv1, &oor);
            if (!oor) {
                r = u8g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetIntegerU8Clamp(rr, clamp, NULL);
            }
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = u8num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = u8g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetIntegerU8Clamp(rr, clamp, NULL);
            }
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
    }
}

ScmObj Scm_U8VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U8VECTOR,
                               SCM_U8VECTOR_SIZE(s0),
                               NULL);
    u8vector_mul("u8vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_U8VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    u8vector_mul("u8vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void s16vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_S16VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S16VECTOR_ELEMENTS(s1)[i];
            r = s16s16_mul(v0, v1, clamp);
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = s16num(vv1, &oor);
            if (!oor) {
                r = s16g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetInteger16Clamp(rr, clamp, NULL);
            }
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = s16num(vv1, &oor);
            if (!oor) {
                r = s16g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetInteger16Clamp(rr, clamp, NULL);
            }
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = s16num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = s16g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetInteger16Clamp(rr, clamp, NULL);
            }
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
    }
}

ScmObj Scm_S16VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S16VECTOR,
                               SCM_S16VECTOR_SIZE(s0),
                               NULL);
    s16vector_mul("s16vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_S16VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    s16vector_mul("s16vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void u16vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_U16VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_U16VECTOR_ELEMENTS(s1)[i];
            r = u16u16_mul(v0, v1, clamp);
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = u16num(vv1, &oor);
            if (!oor) {
                r = u16g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetIntegerU16Clamp(rr, clamp, NULL);
            }
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = u16num(vv1, &oor);
            if (!oor) {
                r = u16g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetIntegerU16Clamp(rr, clamp, NULL);
            }
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = u16num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = u16g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetIntegerU16Clamp(rr, clamp, NULL);
            }
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
    }
}

ScmObj Scm_U16VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U16VECTOR,
                               SCM_U16VECTOR_SIZE(s0),
                               NULL);
    u16vector_mul("u16vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_U16VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    u16vector_mul("u16vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void s32vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_S32VECTOR_SIZE(d), oor;
    long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S32VECTOR_ELEMENTS(s1)[i];
            r = s32s32_mul(v0, v1, clamp);
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = s32num(vv1, &oor);
            if (!oor) {
                r = s32g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetInteger32Clamp(rr, clamp, NULL);
            }
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = s32num(vv1, &oor);
            if (!oor) {
                r = s32g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetInteger32Clamp(rr, clamp, NULL);
            }
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = s32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = s32g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetInteger32Clamp(rr, clamp, NULL);
            }
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
    }
}

ScmObj Scm_S32VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S32VECTOR,
                               SCM_S32VECTOR_SIZE(s0),
                               NULL);
    s32vector_mul("s32vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_S32VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    s32vector_mul("s32vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void u32vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_U32VECTOR_SIZE(d), oor;
    u_long r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            v1 = (u_long)SCM_U32VECTOR_ELEMENTS(s1)[i];
            r = u32u32_mul(v0, v1, clamp);
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = u32num(vv1, &oor);
            if (!oor) {
                r = u32g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetIntegerU32Clamp(rr, clamp, NULL);
            }
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = u32num(vv1, &oor);
            if (!oor) {
                r = u32g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetIntegerU32Clamp(rr, clamp, NULL);
            }
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = u32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = u32g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetIntegerU32Clamp(rr, clamp, NULL);
            }
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
    }
}

ScmObj Scm_U32VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U32VECTOR,
                               SCM_U32VECTOR_SIZE(s0),
                               NULL);
    u32vector_mul("u32vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_U32VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    u32vector_mul("u32vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void s64vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_S64VECTOR_SIZE(d), oor;
    int64_t r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_S64VECTOR_ELEMENTS(s1)[i];
            r = s64s64_mul(v0, v1, clamp);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = s64num(vv1, &oor);
            if (!oor) {
                r = s64g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger64(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetInteger64Clamp(rr, clamp, NULL);
            }
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = s64num(vv1, &oor);
            if (!oor) {
                r = s64g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger64(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetInteger64Clamp(rr, clamp, NULL);
            }
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = s64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = s64g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeInteger64(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetInteger64Clamp(rr, clamp, NULL);
            }
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_S64VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S64VECTOR,
                               SCM_S64VECTOR_SIZE(s0),
                               NULL);
    s64vector_mul("s64vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_S64VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    s64vector_mul("s64vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void u64vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_U64VECTOR_SIZE(d), oor;
    uint64_t r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_U64VECTOR_ELEMENTS(s1)[i];
            r = u64u64_mul(v0, v1, clamp);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = u64num(vv1, &oor);
            if (!oor) {
                r = u64g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU64(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetIntegerU64Clamp(rr, clamp, NULL);
            }
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = u64num(vv1, &oor);
            if (!oor) {
                r = u64g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU64(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetIntegerU64Clamp(rr, clamp, NULL);
            }
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = u64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = u64g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeIntegerU64(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetIntegerU64Clamp(rr, clamp, NULL);
            }
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_U64VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U64VECTOR,
                               SCM_U64VECTOR_SIZE(s0),
                               NULL);
    u64vector_mul("u64vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_U64VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    u64vector_mul("u64vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void f16vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_F16VECTOR_SIZE(d), oor;
    double r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            v1 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s1)[i]);
            r = f16f16_mul(v0, v1, clamp);
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = f16num(vv1, &oor);
            if (!oor) {
                r = f16g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = f16num(vv1, &oor);
            if (!oor) {
                r = f16g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = f16num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            if (!oor) {
                r = f16g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetDouble(rr);
            }
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
    }
}

ScmObj Scm_F16VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_F16VECTOR,
                               SCM_F16VECTOR_SIZE(s0),
                               NULL);
    f16vector_mul("f16vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_F16VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    f16vector_mul("f16vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void f32vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_F32VECTOR_SIZE(d), oor;
    double r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            v1 = (double)SCM_F32VECTOR_ELEMENTS(s1)[i];
            r = f32f32_mul(v0, v1, clamp);
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = f32num(vv1, &oor);
            if (!oor) {
                r = f32g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = f32num(vv1, &oor);
            if (!oor) {
                r = f32g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = f32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = f32g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetDouble(rr);
            }
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
    }
}

ScmObj Scm_F32VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_F32VECTOR,
                               SCM_F32VECTOR_SIZE(s0),
                               NULL);
    f32vector_mul("f32vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_F32VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    f32vector_mul("f32vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void f64vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_F64VECTOR_SIZE(d), oor;
    double r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_F64VECTOR_ELEMENTS(s1)[i];
            r = f64f64_mul(v0, v1, clamp);
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = f64num(vv1, &oor);
            if (!oor) {
                r = f64g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = f64num(vv1, &oor);
            if (!oor) {
                r = f64g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = f64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = f64g_mul(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetDouble(rr);
            }
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_F64VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_F64VECTOR,
                               SCM_F64VECTOR_SIZE(s0),
                               NULL);
    f64vector_mul("f64vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_F64VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    f64vector_mul("f64vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void c32vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_C32VECTOR_SIZE(d), oor;
    ScmHalfComplex r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_C32VECTOR_ELEMENTS(s1)[i];
            r = c32c32_mul(v0, v1, clamp);
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = c32num(vv1, &oor);
            if (!oor) {
                r = c32g_mul(v0, v1, clamp);
            } else {
                rr = Scm_HalfComplexToComplex(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetHalfComplex(rr);
            }
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = c32num(vv1, &oor);
            if (!oor) {
                r = c32g_mul(v0, v1, clamp);
            } else {
                rr = Scm_HalfComplexToComplex(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetHalfComplex(rr);
            }
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = c32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = c32g_mul(v0, v1, clamp);
            } else {
                rr = Scm_HalfComplexToComplex(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetHalfComplex(rr);
            }
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_C32VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_C32VECTOR,
                               SCM_C32VECTOR_SIZE(s0),
                               NULL);
    c32vector_mul("c32vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_C32VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    c32vector_mul("c32vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void c64vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_C64VECTOR_SIZE(d), oor;
    ScmFloatComplex r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_C64VECTOR_ELEMENTS(s1)[i];
            r = c64c64_mul(v0, v1, clamp);
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = c64num(vv1, &oor);
            if (!oor) {
                r = c64g_mul(v0, v1, clamp);
            } else {
                rr = Scm_FloatComplexToComplex(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetFloatComplex(rr);
            }
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = c64num(vv1, &oor);
            if (!oor) {
                r = c64g_mul(v0, v1, clamp);
            } else {
                rr = Scm_FloatComplexToComplex(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetFloatComplex(rr);
            }
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = c64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = c64g_mul(v0, v1, clamp);
            } else {
                rr = Scm_FloatComplexToComplex(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetFloatComplex(rr);
            }
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_C64VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_C64VECTOR,
                               SCM_C64VECTOR_SIZE(s0),
                               NULL);
    c64vector_mul("c64vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_C64VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    c64vector_mul("c64vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void c128vector_mul(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_C128VECTOR_SIZE(d), oor;
    ScmDoubleComplex r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_C128VECTOR_ELEMENTS(s1)[i];
            r = c128c128_mul(v0, v1, clamp);
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = c128num(vv1, &oor);
            if (!oor) {
                r = c128g_mul(v0, v1, clamp);
            } else {
                rr = Scm_DoubleComplexToComplex(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetDoubleComplex(rr);
            }
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = c128num(vv1, &oor);
            if (!oor) {
                r = c128g_mul(v0, v1, clamp);
            } else {
                rr = Scm_DoubleComplexToComplex(v0);
                rr = Scm_Mul(rr, vv1);
                r = Scm_GetDoubleComplex(rr);
            }
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = c128num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = c128g_mul(v0, v1, clamp);
            } else {
                rr = Scm_DoubleComplexToComplex(v0);
                rr = Scm_Mul(rr, s1);
                r = Scm_GetDoubleComplex(rr);
            }
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_C128VectorMul(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_C128VECTOR,
                               SCM_C128VECTOR_SIZE(s0),
                               NULL);
    c128vector_mul("c128vector-mul", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_C128VectorMulX(ScmUVector *s0, ScmObj s1, int clamp)
{
    c128vector_mul("c128vector-mul!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void f16vector_div(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_F16VECTOR_SIZE(d), oor;
    double r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            v1 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s1)[i]);
            r = f16f16_div(v0, v1, clamp);
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = f16num(vv1, &oor);
            if (!oor) {
                r = f16g_div(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Div(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = f16num(vv1, &oor);
            if (!oor) {
                r = f16g_div(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Div(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = f16num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(s0)[i]);
            if (!oor) {
                r = f16g_div(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Div(rr, s1);
                r = Scm_GetDouble(rr);
            }
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(r);
        }
    }
}

ScmObj Scm_F16VectorDiv(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_F16VECTOR,
                               SCM_F16VECTOR_SIZE(s0),
                               NULL);
    f16vector_div("f16vector-div", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_F16VectorDivX(ScmUVector *s0, ScmObj s1, int clamp)
{
    f16vector_div("f16vector-div!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void f32vector_div(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_F32VECTOR_SIZE(d), oor;
    double r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            v1 = (double)SCM_F32VECTOR_ELEMENTS(s1)[i];
            r = f32f32_div(v0, v1, clamp);
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = f32num(vv1, &oor);
            if (!oor) {
                r = f32g_div(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Div(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = f32num(vv1, &oor);
            if (!oor) {
                r = f32g_div(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Div(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = f32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = (double)SCM_F32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = f32g_div(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Div(rr, s1);
                r = Scm_GetDouble(rr);
            }
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(r);
        }
    }
}

ScmObj Scm_F32VectorDiv(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_F32VECTOR,
                               SCM_F32VECTOR_SIZE(s0),
                               NULL);
    f32vector_div("f32vector-div", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_F32VectorDivX(ScmUVector *s0, ScmObj s1, int clamp)
{
    f32vector_div("f32vector-div!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void f64vector_div(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_F64VECTOR_SIZE(d), oor;
    double r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_F64VECTOR_ELEMENTS(s1)[i];
            r = f64f64_div(v0, v1, clamp);
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = f64num(vv1, &oor);
            if (!oor) {
                r = f64g_div(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Div(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = f64num(vv1, &oor);
            if (!oor) {
                r = f64g_div(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Div(rr, vv1);
                r = Scm_GetDouble(rr);
            }
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = f64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_F64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = f64g_div(v0, v1, clamp);
            } else {
                rr = Scm_MakeFlonum(v0);
                rr = Scm_Div(rr, s1);
                r = Scm_GetDouble(rr);
            }
            SCM_F64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_F64VectorDiv(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_F64VECTOR,
                               SCM_F64VECTOR_SIZE(s0),
                               NULL);
    f64vector_div("f64vector-div", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_F64VectorDivX(ScmUVector *s0, ScmObj s1, int clamp)
{
    f64vector_div("f64vector-div!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void c32vector_div(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_C32VECTOR_SIZE(d), oor;
    ScmHalfComplex r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_C32VECTOR_ELEMENTS(s1)[i];
            r = c32c32_div(v0, v1, clamp);
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = c32num(vv1, &oor);
            if (!oor) {
                r = c32g_div(v0, v1, clamp);
            } else {
                rr = Scm_HalfComplexToComplex(v0);
                rr = Scm_Div(rr, vv1);
                r = Scm_GetHalfComplex(rr);
            }
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = c32num(vv1, &oor);
            if (!oor) {
                r = c32g_div(v0, v1, clamp);
            } else {
                rr = Scm_HalfComplexToComplex(v0);
                rr = Scm_Div(rr, vv1);
                r = Scm_GetHalfComplex(rr);
            }
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = c32num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_C32VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = c32g_div(v0, v1, clamp);
            } else {
                rr = Scm_HalfComplexToComplex(v0);
                rr = Scm_Div(rr, s1);
                r = Scm_GetHalfComplex(rr);
            }
            SCM_C32VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_C32VectorDiv(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_C32VECTOR,
                               SCM_C32VECTOR_SIZE(s0),
                               NULL);
    c32vector_div("c32vector-div", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_C32VectorDivX(ScmUVector *s0, ScmObj s1, int clamp)
{
    c32vector_div("c32vector-div!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void c64vector_div(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_C64VECTOR_SIZE(d), oor;
    ScmFloatComplex r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_C64VECTOR_ELEMENTS(s1)[i];
            r = c64c64_div(v0, v1, clamp);
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = c64num(vv1, &oor);
            if (!oor) {
                r = c64g_div(v0, v1, clamp);
            } else {
                rr = Scm_FloatComplexToComplex(v0);
                rr = Scm_Div(rr, vv1);
                r = Scm_GetFloatComplex(rr);
            }
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = c64num(vv1, &oor);
            if (!oor) {
                r = c64g_div(v0, v1, clamp);
            } else {
                rr = Scm_FloatComplexToComplex(v0);
                rr = Scm_Div(rr, vv1);
                r = Scm_GetFloatComplex(rr);
            }
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = c64num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_C64VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = c64g_div(v0, v1, clamp);
            } else {
                rr = Scm_FloatComplexToComplex(v0);
                rr = Scm_Div(rr, s1);
                r = Scm_GetFloatComplex(rr);
            }
            SCM_C64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_C64VectorDiv(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_C64VECTOR,
                               SCM_C64VECTOR_SIZE(s0),
                               NULL);
    c64vector_div("c64vector-div", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_C64VectorDivX(ScmUVector *s0, ScmObj s1, int clamp)
{
    c64vector_div("c64vector-div!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

/* NB: s1 can be a register flonum. */
static void c128vector_div(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1, 
                                 int clamp SCM_UNUSED)
                                /* clamp appears in macro call below, but
                                   the macro may not use it. */
{
    int size = SCM_C128VECTOR_SIZE(d), oor;
    ScmDoubleComplex r, v0, v1;
    ScmObj rr, vv1;

    switch (arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_C128VECTOR_ELEMENTS(s1)[i];
            r = c128c128_div(v0, v1, clamp);
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = c128num(vv1, &oor);
            if (!oor) {
                r = c128g_div(v0, v1, clamp);
            } else {
                rr = Scm_DoubleComplexToComplex(v0);
                rr = Scm_Div(rr, vv1);
                r = Scm_GetDoubleComplex(rr);
            }
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_CAR(s1); s1 = SCM_CDR(s1);
            v1 = c128num(vv1, &oor);
            if (!oor) {
                r = c128g_div(v0, v1, clamp);
            } else {
                rr = Scm_DoubleComplexToComplex(v0);
                rr = Scm_Div(rr, vv1);
                r = Scm_GetDoubleComplex(rr);
            }
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = c128num(s1, &oor);
        for (int i=0; i<size; i++) {
            v0 = SCM_C128VECTOR_ELEMENTS(s0)[i];
            if (!oor) {
                r = c128g_div(v0, v1, clamp);
            } else {
                rr = Scm_DoubleComplexToComplex(v0);
                rr = Scm_Div(rr, s1);
                r = Scm_GetDoubleComplex(rr);
            }
            SCM_C128VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_C128VectorDiv(ScmUVector *s0, ScmObj s1, int clamp)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_C128VECTOR,
                               SCM_C128VECTOR_SIZE(s0),
                               NULL);
    c128vector_div("c128vector-div", d, SCM_OBJ(s0), s1, clamp);
    return d;
}

ScmObj Scm_C128VectorDivX(ScmUVector *s0, ScmObj s1, int clamp)
{
    c128vector_div("c128vector-div!", SCM_OBJ(s0), SCM_OBJ(s0), s1, clamp);
    return SCM_OBJ(s0);
}

static void s8vector_and(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_S8VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S8VECTOR_ELEMENTS(s1)[i];
            r = v0 & v1;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 & v1;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 & v1;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            r = v0 & v1;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
    }
}

ScmObj Scm_S8VectorAnd(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S8VECTOR,
                               SCM_S8VECTOR_SIZE(s0),
                               NULL);
    s8vector_and("s8vector-and", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_S8VectorAndX(ScmUVector *s0, ScmObj s1)
{
    s8vector_and("s8vector-and!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void s8vector_ior(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_S8VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S8VECTOR_ELEMENTS(s1)[i];
            r = v0 | v1;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 | v1;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 | v1;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            r = v0 | v1;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
    }
}

ScmObj Scm_S8VectorIor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S8VECTOR,
                               SCM_S8VECTOR_SIZE(s0),
                               NULL);
    s8vector_ior("s8vector-ior", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_S8VectorIorX(ScmUVector *s0, ScmObj s1)
{
    s8vector_ior("s8vector-ior!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void s8vector_xor(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_S8VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S8VECTOR_ELEMENTS(s1)[i];
            r = v0 ^ v1;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 ^ v1;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 ^ v1;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S8VECTOR_ELEMENTS(s0)[i];
            r = v0 ^ v1;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(r);
        }
    }
}

ScmObj Scm_S8VectorXor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S8VECTOR,
                               SCM_S8VECTOR_SIZE(s0),
                               NULL);
    s8vector_xor("s8vector-xor", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_S8VectorXorX(ScmUVector *s0, ScmObj s1)
{
    s8vector_xor("s8vector-xor!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void u8vector_and(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_U8VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_U8VECTOR_ELEMENTS(s1)[i];
            r = v0 & v1;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 & v1;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 & v1;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            r = v0 & v1;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
    }
}

ScmObj Scm_U8VectorAnd(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U8VECTOR,
                               SCM_U8VECTOR_SIZE(s0),
                               NULL);
    u8vector_and("u8vector-and", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_U8VectorAndX(ScmUVector *s0, ScmObj s1)
{
    u8vector_and("u8vector-and!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void u8vector_ior(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_U8VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_U8VECTOR_ELEMENTS(s1)[i];
            r = v0 | v1;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 | v1;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 | v1;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            r = v0 | v1;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
    }
}

ScmObj Scm_U8VectorIor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U8VECTOR,
                               SCM_U8VECTOR_SIZE(s0),
                               NULL);
    u8vector_ior("u8vector-ior", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_U8VectorIorX(ScmUVector *s0, ScmObj s1)
{
    u8vector_ior("u8vector-ior!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void u8vector_xor(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_U8VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_U8VECTOR_ELEMENTS(s1)[i];
            r = v0 ^ v1;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 ^ v1;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 ^ v1;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U8VECTOR_ELEMENTS(s0)[i];
            r = v0 ^ v1;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(r);
        }
    }
}

ScmObj Scm_U8VectorXor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U8VECTOR,
                               SCM_U8VECTOR_SIZE(s0),
                               NULL);
    u8vector_xor("u8vector-xor", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_U8VectorXorX(ScmUVector *s0, ScmObj s1)
{
    u8vector_xor("u8vector-xor!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void s16vector_and(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_S16VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S16VECTOR_ELEMENTS(s1)[i];
            r = v0 & v1;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 & v1;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 & v1;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            r = v0 & v1;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
    }
}

ScmObj Scm_S16VectorAnd(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S16VECTOR,
                               SCM_S16VECTOR_SIZE(s0),
                               NULL);
    s16vector_and("s16vector-and", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_S16VectorAndX(ScmUVector *s0, ScmObj s1)
{
    s16vector_and("s16vector-and!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void s16vector_ior(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_S16VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S16VECTOR_ELEMENTS(s1)[i];
            r = v0 | v1;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 | v1;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 | v1;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            r = v0 | v1;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
    }
}

ScmObj Scm_S16VectorIor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S16VECTOR,
                               SCM_S16VECTOR_SIZE(s0),
                               NULL);
    s16vector_ior("s16vector-ior", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_S16VectorIorX(ScmUVector *s0, ScmObj s1)
{
    s16vector_ior("s16vector-ior!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void s16vector_xor(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_S16VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S16VECTOR_ELEMENTS(s1)[i];
            r = v0 ^ v1;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 ^ v1;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 ^ v1;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S16VECTOR_ELEMENTS(s0)[i];
            r = v0 ^ v1;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(r);
        }
    }
}

ScmObj Scm_S16VectorXor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S16VECTOR,
                               SCM_S16VECTOR_SIZE(s0),
                               NULL);
    s16vector_xor("s16vector-xor", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_S16VectorXorX(ScmUVector *s0, ScmObj s1)
{
    s16vector_xor("s16vector-xor!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void u16vector_and(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_U16VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_U16VECTOR_ELEMENTS(s1)[i];
            r = v0 & v1;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 & v1;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 & v1;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            r = v0 & v1;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
    }
}

ScmObj Scm_U16VectorAnd(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U16VECTOR,
                               SCM_U16VECTOR_SIZE(s0),
                               NULL);
    u16vector_and("u16vector-and", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_U16VectorAndX(ScmUVector *s0, ScmObj s1)
{
    u16vector_and("u16vector-and!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void u16vector_ior(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_U16VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_U16VECTOR_ELEMENTS(s1)[i];
            r = v0 | v1;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 | v1;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 | v1;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            r = v0 | v1;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
    }
}

ScmObj Scm_U16VectorIor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U16VECTOR,
                               SCM_U16VECTOR_SIZE(s0),
                               NULL);
    u16vector_ior("u16vector-ior", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_U16VectorIorX(ScmUVector *s0, ScmObj s1)
{
    u16vector_ior("u16vector-ior!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void u16vector_xor(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_U16VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_U16VECTOR_ELEMENTS(s1)[i];
            r = v0 ^ v1;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 ^ v1;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 ^ v1;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_U16VECTOR_ELEMENTS(s0)[i];
            r = v0 ^ v1;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(r);
        }
    }
}

ScmObj Scm_U16VectorXor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U16VECTOR,
                               SCM_U16VECTOR_SIZE(s0),
                               NULL);
    u16vector_xor("u16vector-xor", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_U16VectorXorX(ScmUVector *s0, ScmObj s1)
{
    u16vector_xor("u16vector-xor!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void s32vector_and(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_S32VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S32VECTOR_ELEMENTS(s1)[i];
            r = v0 & v1;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 & v1;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 & v1;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            r = v0 & v1;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
    }
}

ScmObj Scm_S32VectorAnd(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S32VECTOR,
                               SCM_S32VECTOR_SIZE(s0),
                               NULL);
    s32vector_and("s32vector-and", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_S32VectorAndX(ScmUVector *s0, ScmObj s1)
{
    s32vector_and("s32vector-and!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void s32vector_ior(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_S32VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S32VECTOR_ELEMENTS(s1)[i];
            r = v0 | v1;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 | v1;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 | v1;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            r = v0 | v1;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
    }
}

ScmObj Scm_S32VectorIor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S32VECTOR,
                               SCM_S32VECTOR_SIZE(s0),
                               NULL);
    s32vector_ior("s32vector-ior", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_S32VectorIorX(ScmUVector *s0, ScmObj s1)
{
    s32vector_ior("s32vector-ior!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void s32vector_xor(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_S32VECTOR_SIZE(d);
    long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            v1 = (long)SCM_S32VECTOR_ELEMENTS(s1)[i];
            r = v0 ^ v1;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 ^ v1;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 ^ v1;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (long)SCM_S32VECTOR_ELEMENTS(s0)[i];
            r = v0 ^ v1;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(r);
        }
    }
}

ScmObj Scm_S32VectorXor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S32VECTOR,
                               SCM_S32VECTOR_SIZE(s0),
                               NULL);
    s32vector_xor("s32vector-xor", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_S32VectorXorX(ScmUVector *s0, ScmObj s1)
{
    s32vector_xor("s32vector-xor!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void u32vector_and(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_U32VECTOR_SIZE(d);
    u_long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            v1 = (u_long)SCM_U32VECTOR_ELEMENTS(s1)[i];
            r = v0 & v1;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 & v1;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 & v1;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            r = v0 & v1;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
    }
}

ScmObj Scm_U32VectorAnd(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U32VECTOR,
                               SCM_U32VECTOR_SIZE(s0),
                               NULL);
    u32vector_and("u32vector-and", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_U32VectorAndX(ScmUVector *s0, ScmObj s1)
{
    u32vector_and("u32vector-and!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void u32vector_ior(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_U32VECTOR_SIZE(d);
    u_long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            v1 = (u_long)SCM_U32VECTOR_ELEMENTS(s1)[i];
            r = v0 | v1;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 | v1;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 | v1;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            r = v0 | v1;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
    }
}

ScmObj Scm_U32VectorIor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U32VECTOR,
                               SCM_U32VECTOR_SIZE(s0),
                               NULL);
    u32vector_ior("u32vector-ior", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_U32VectorIorX(ScmUVector *s0, ScmObj s1)
{
    u32vector_ior("u32vector-ior!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void u32vector_xor(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_U32VECTOR_SIZE(d);
    u_long r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            v1 = (u_long)SCM_U32VECTOR_ELEMENTS(s1)[i];
            r = v0 ^ v1;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 ^ v1;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext(vv1);
            r = v0 ^ v1;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext(s1);
        for (int i=0; i<size; i++) {
            v0 = (u_long)SCM_U32VECTOR_ELEMENTS(s0)[i];
            r = v0 ^ v1;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(r);
        }
    }
}

ScmObj Scm_U32VectorXor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U32VECTOR,
                               SCM_U32VECTOR_SIZE(s0),
                               NULL);
    u32vector_xor("u32vector-xor", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_U32VectorXorX(ScmUVector *s0, ScmObj s1)
{
    u32vector_xor("u32vector-xor!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void s64vector_and(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_S64VECTOR_SIZE(d);
    int64_t r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_S64VECTOR_ELEMENTS(s1)[i];
            INT64BITOP(r, v0, &, v1);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext64(vv1);
            INT64BITOP(r, v0, &, v1);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext64(vv1);
            INT64BITOP(r, v0, &, v1);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext64(s1);
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            INT64BITOP(r, v0, &, v1);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_S64VectorAnd(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S64VECTOR,
                               SCM_S64VECTOR_SIZE(s0),
                               NULL);
    s64vector_and("s64vector-and", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_S64VectorAndX(ScmUVector *s0, ScmObj s1)
{
    s64vector_and("s64vector-and!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void s64vector_ior(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_S64VECTOR_SIZE(d);
    int64_t r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_S64VECTOR_ELEMENTS(s1)[i];
            INT64BITOP(r, v0, |, v1);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext64(vv1);
            INT64BITOP(r, v0, |, v1);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext64(vv1);
            INT64BITOP(r, v0, |, v1);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext64(s1);
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            INT64BITOP(r, v0, |, v1);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_S64VectorIor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S64VECTOR,
                               SCM_S64VECTOR_SIZE(s0),
                               NULL);
    s64vector_ior("s64vector-ior", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_S64VectorIorX(ScmUVector *s0, ScmObj s1)
{
    s64vector_ior("s64vector-ior!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void s64vector_xor(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_S64VECTOR_SIZE(d);
    int64_t r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_S64VECTOR_ELEMENTS(s1)[i];
            INT64BITOP(r, v0, ^, v1);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext64(vv1);
            INT64BITOP(r, v0, ^, v1);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext64(vv1);
            INT64BITOP(r, v0, ^, v1);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext64(s1);
        for (int i=0; i<size; i++) {
            v0 = SCM_S64VECTOR_ELEMENTS(s0)[i];
            INT64BITOP(r, v0, ^, v1);
            SCM_S64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_S64VectorXor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_S64VECTOR,
                               SCM_S64VECTOR_SIZE(s0),
                               NULL);
    s64vector_xor("s64vector-xor", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_S64VectorXorX(ScmUVector *s0, ScmObj s1)
{
    s64vector_xor("s64vector-xor!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void u64vector_and(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_U64VECTOR_SIZE(d);
    uint64_t r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_U64VECTOR_ELEMENTS(s1)[i];
            INT64BITOP(r, v0, &, v1);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext64(vv1);
            INT64BITOP(r, v0, &, v1);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext64(vv1);
            INT64BITOP(r, v0, &, v1);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext64(s1);
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            INT64BITOP(r, v0, &, v1);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_U64VectorAnd(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U64VECTOR,
                               SCM_U64VECTOR_SIZE(s0),
                               NULL);
    u64vector_and("u64vector-and", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_U64VectorAndX(ScmUVector *s0, ScmObj s1)
{
    u64vector_and("u64vector-and!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void u64vector_ior(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_U64VECTOR_SIZE(d);
    uint64_t r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_U64VECTOR_ELEMENTS(s1)[i];
            INT64BITOP(r, v0, |, v1);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext64(vv1);
            INT64BITOP(r, v0, |, v1);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext64(vv1);
            INT64BITOP(r, v0, |, v1);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext64(s1);
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            INT64BITOP(r, v0, |, v1);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_U64VectorIor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U64VECTOR,
                               SCM_U64VECTOR_SIZE(s0),
                               NULL);
    u64vector_ior("u64vector-ior", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_U64VectorIorX(ScmUVector *s0, ScmObj s1)
{
    u64vector_ior("u64vector-ior!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static void u64vector_xor(const char *name,
                                 ScmObj d, ScmObj s0, ScmObj s1)
{
    int size = SCM_U64VECTOR_SIZE(d);
    uint64_t r, v0, v1;
    ScmObj vv1;

    switch(arg2_check(name, s0, s1, TRUE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            v1 = SCM_U64VECTOR_ELEMENTS(s1)[i];
            INT64BITOP(r, v0, ^, v1);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext64(vv1);
            INT64BITOP(r, v0, ^, v1);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            vv1 = SCM_VECTOR_ELEMENTS(s1)[i];
            v1 = bitext64(vv1);
            INT64BITOP(r, v0, ^, v1);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
        break;
    case ARGTYPE_CONST:
        v1 = bitext64(s1);
        for (int i=0; i<size; i++) {
            v0 = SCM_U64VECTOR_ELEMENTS(s0)[i];
            INT64BITOP(r, v0, ^, v1);
            SCM_U64VECTOR_ELEMENTS(d)[i] = r;
        }
    }
}

ScmObj Scm_U64VectorXor(ScmUVector *s0, ScmObj s1)
{
    ScmObj d = Scm_MakeUVector(SCM_CLASS_U64VECTOR,
                               SCM_U64VECTOR_SIZE(s0),
                               NULL);
    u64vector_xor("u64vector-xor", d, SCM_OBJ(s0), s1);
    return d;
}

ScmObj Scm_U64VectorXorX(ScmUVector *s0, ScmObj s1)
{
    u64vector_xor("u64vector-xor!", SCM_OBJ(s0), SCM_OBJ(s0), s1);
    return SCM_OBJ(s0);
}
static ScmObj S8VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_S8VECTOR_SIZE(x), oor;
    long r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("s8vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_S8VECTOR_ELEMENTS(x)[i];
            vy = (long)SCM_S8VECTOR_ELEMENTS(y)[i];
            r = s8muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_S8VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = s8num(vvy, &oor);
            if (!oor) {
                r = s8muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeInteger(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_S8VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = s8num(vvy, &oor);
            if (!oor) {
                r = s8muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeInteger(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of s8vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_MakeInteger(r);
        } else {
            rr = Scm_MakeInteger(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_MakeInteger(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_S8VectorDotProd(ScmUVector *x, ScmObj y)
{
    return S8VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMS8VectorDotProd(ScmUVector *x, ScmObj y)
{
    return S8VectorDotProd(x, y, TRUE);
}
static ScmObj U8VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_U8VECTOR_SIZE(x), oor;
    long r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("u8vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_U8VECTOR_ELEMENTS(x)[i];
            vy = (long)SCM_U8VECTOR_ELEMENTS(y)[i];
            r = u8muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_U8VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = u8num(vvy, &oor);
            if (!oor) {
                r = u8muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeIntegerU(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_U8VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = u8num(vvy, &oor);
            if (!oor) {
                r = u8muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeIntegerU(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of u8vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_MakeIntegerU(r);
        } else {
            rr = Scm_MakeIntegerU(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_MakeIntegerU(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_U8VectorDotProd(ScmUVector *x, ScmObj y)
{
    return U8VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMU8VectorDotProd(ScmUVector *x, ScmObj y)
{
    return U8VectorDotProd(x, y, TRUE);
}
static ScmObj S16VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_S16VECTOR_SIZE(x), oor;
    long r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("s16vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_S16VECTOR_ELEMENTS(x)[i];
            vy = (long)SCM_S16VECTOR_ELEMENTS(y)[i];
            r = s16muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_S16VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = s16num(vvy, &oor);
            if (!oor) {
                r = s16muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeInteger(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_S16VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = s16num(vvy, &oor);
            if (!oor) {
                r = s16muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeInteger(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of s16vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_MakeInteger(r);
        } else {
            rr = Scm_MakeInteger(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_MakeInteger(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_S16VectorDotProd(ScmUVector *x, ScmObj y)
{
    return S16VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMS16VectorDotProd(ScmUVector *x, ScmObj y)
{
    return S16VectorDotProd(x, y, TRUE);
}
static ScmObj U16VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_U16VECTOR_SIZE(x), oor;
    long r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("u16vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_U16VECTOR_ELEMENTS(x)[i];
            vy = (long)SCM_U16VECTOR_ELEMENTS(y)[i];
            r = u16muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_U16VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = u16num(vvy, &oor);
            if (!oor) {
                r = u16muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeIntegerU(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_U16VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = u16num(vvy, &oor);
            if (!oor) {
                r = u16muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeIntegerU(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of u16vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_MakeIntegerU(r);
        } else {
            rr = Scm_MakeIntegerU(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_MakeIntegerU(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_U16VectorDotProd(ScmUVector *x, ScmObj y)
{
    return U16VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMU16VectorDotProd(ScmUVector *x, ScmObj y)
{
    return U16VectorDotProd(x, y, TRUE);
}
static ScmObj S32VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_S32VECTOR_SIZE(x), oor;
    long r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("s32vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_S32VECTOR_ELEMENTS(x)[i];
            vy = (long)SCM_S32VECTOR_ELEMENTS(y)[i];
            r = s32muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_S32VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = s32num(vvy, &oor);
            if (!oor) {
                r = s32muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeInteger(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = (long)SCM_S32VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = s32num(vvy, &oor);
            if (!oor) {
                r = s32muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeInteger(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of s32vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_MakeInteger(r);
        } else {
            rr = Scm_MakeInteger(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_MakeInteger(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_S32VectorDotProd(ScmUVector *x, ScmObj y)
{
    return S32VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMS32VectorDotProd(ScmUVector *x, ScmObj y)
{
    return S32VectorDotProd(x, y, TRUE);
}
static ScmObj U32VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_U32VECTOR_SIZE(x), oor;
    u_long r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("u32vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = (u_long)SCM_U32VECTOR_ELEMENTS(x)[i];
            vy = (u_long)SCM_U32VECTOR_ELEMENTS(y)[i];
            r = u32muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = (u_long)SCM_U32VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = u32num(vvy, &oor);
            if (!oor) {
                r = u32muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeIntegerU(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = (u_long)SCM_U32VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = u32num(vvy, &oor);
            if (!oor) {
                r = u32muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeIntegerU(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of u32vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_MakeIntegerU(r);
        } else {
            rr = Scm_MakeIntegerU(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_MakeIntegerU(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_U32VectorDotProd(ScmUVector *x, ScmObj y)
{
    return U32VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMU32VectorDotProd(ScmUVector *x, ScmObj y)
{
    return U32VectorDotProd(x, y, TRUE);
}
static ScmObj S64VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_S64VECTOR_SIZE(x), oor;
    int64_t r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("s64vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = SCM_S64VECTOR_ELEMENTS(x)[i];
            vy = SCM_S64VECTOR_ELEMENTS(y)[i];
            r = s64muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = SCM_S64VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = s64num(vvy, &oor);
            if (!oor) {
                r = s64muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeInteger64(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = SCM_S64VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = s64num(vvy, &oor);
            if (!oor) {
                r = s64muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeInteger64(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of s64vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_MakeInteger64(r);
        } else {
            rr = Scm_MakeInteger64(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_MakeInteger64(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_S64VectorDotProd(ScmUVector *x, ScmObj y)
{
    return S64VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMS64VectorDotProd(ScmUVector *x, ScmObj y)
{
    return S64VectorDotProd(x, y, TRUE);
}
static ScmObj U64VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_U64VECTOR_SIZE(x), oor;
    uint64_t r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("u64vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = SCM_U64VECTOR_ELEMENTS(x)[i];
            vy = SCM_U64VECTOR_ELEMENTS(y)[i];
            r = u64muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = SCM_U64VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = u64num(vvy, &oor);
            if (!oor) {
                r = u64muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeIntegerU64(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = SCM_U64VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = u64num(vvy, &oor);
            if (!oor) {
                r = u64muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeIntegerU64(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of u64vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_MakeIntegerU64(r);
        } else {
            rr = Scm_MakeIntegerU64(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_MakeIntegerU64(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_U64VectorDotProd(ScmUVector *x, ScmObj y)
{
    return U64VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMU64VectorDotProd(ScmUVector *x, ScmObj y)
{
    return U64VectorDotProd(x, y, TRUE);
}
static ScmObj F16VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_F16VECTOR_SIZE(x), oor;
    double r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("f16vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(x)[i]);
            vy = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(y)[i]);
            r = f16muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(x)[i]);
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = f16num(vvy, &oor);
            if (!oor) {
                r = f16muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeFlonum(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(x)[i]);
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = f16num(vvy, &oor);
            if (!oor) {
                r = f16muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeFlonum(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of f16vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_VMReturnFlonum(r);
        } else {
            rr = Scm_MakeFlonum(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_MakeFlonum(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_F16VectorDotProd(ScmUVector *x, ScmObj y)
{
    return F16VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMF16VectorDotProd(ScmUVector *x, ScmObj y)
{
    return F16VectorDotProd(x, y, TRUE);
}
static ScmObj F32VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_F32VECTOR_SIZE(x), oor;
    double r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("f32vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = (double)SCM_F32VECTOR_ELEMENTS(x)[i];
            vy = (double)SCM_F32VECTOR_ELEMENTS(y)[i];
            r = f32muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = (double)SCM_F32VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = f32num(vvy, &oor);
            if (!oor) {
                r = f32muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeFlonum(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = (double)SCM_F32VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = f32num(vvy, &oor);
            if (!oor) {
                r = f32muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeFlonum(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of f32vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_VMReturnFlonum(r);
        } else {
            rr = Scm_MakeFlonum(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_MakeFlonum(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_F32VectorDotProd(ScmUVector *x, ScmObj y)
{
    return F32VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMF32VectorDotProd(ScmUVector *x, ScmObj y)
{
    return F32VectorDotProd(x, y, TRUE);
}
static ScmObj F64VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_F64VECTOR_SIZE(x), oor;
    double r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("f64vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = SCM_F64VECTOR_ELEMENTS(x)[i];
            vy = SCM_F64VECTOR_ELEMENTS(y)[i];
            r = f64muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = SCM_F64VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = f64num(vvy, &oor);
            if (!oor) {
                r = f64muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeFlonum(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = SCM_F64VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = f64num(vvy, &oor);
            if (!oor) {
                r = f64muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_MakeFlonum(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of f64vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_MakeFlonum(r);
        } else {
            rr = Scm_MakeFlonum(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_MakeFlonum(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_F64VectorDotProd(ScmUVector *x, ScmObj y)
{
    return F64VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMF64VectorDotProd(ScmUVector *x, ScmObj y)
{
    return F64VectorDotProd(x, y, TRUE);
}
static ScmObj C32VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_C32VECTOR_SIZE(x), oor;
    ScmHalfComplex r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = (ScmHalfComplex){0, 0};
    switch (arg2_check("c32vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = SCM_C32VECTOR_ELEMENTS(x)[i];
            vy = SCM_C32VECTOR_ELEMENTS(y)[i];
            r = c32muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = SCM_C32VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = c32num(vvy, &oor);
            if (!oor) {
                r = c32muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_HalfComplexToComplex(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = SCM_C32VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = c32num(vvy, &oor);
            if (!oor) {
                r = c32muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_HalfComplexToComplex(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of c32vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_HalfComplexToComplex(r);
        } else {
            rr = Scm_HalfComplexToComplex(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_HalfComplexToComplex(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_C32VectorDotProd(ScmUVector *x, ScmObj y)
{
    return C32VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMC32VectorDotProd(ScmUVector *x, ScmObj y)
{
    return C32VectorDotProd(x, y, TRUE);
}
static ScmObj C64VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_C64VECTOR_SIZE(x), oor;
    ScmFloatComplex r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("c64vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = SCM_C64VECTOR_ELEMENTS(x)[i];
            vy = SCM_C64VECTOR_ELEMENTS(y)[i];
            r = c64muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = SCM_C64VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = c64num(vvy, &oor);
            if (!oor) {
                r = c64muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_FloatComplexToComplex(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = SCM_C64VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = c64num(vvy, &oor);
            if (!oor) {
                r = c64muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_FloatComplexToComplex(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of c64vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_FloatComplexToComplex(r);
        } else {
            rr = Scm_FloatComplexToComplex(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_FloatComplexToComplex(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_C64VectorDotProd(ScmUVector *x, ScmObj y)
{
    return C64VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMC64VectorDotProd(ScmUVector *x, ScmObj y)
{
    return C64VectorDotProd(x, y, TRUE);
}
static ScmObj C128VectorDotProd(ScmUVector *x, ScmObj y, int vmp)
{
    int size = SCM_C128VECTOR_SIZE(x), oor;
    ScmDoubleComplex r, vx, vy;
    ScmObj rr = SCM_MAKE_INT(0), vvy, vvx;

    r = 0;
    switch (arg2_check("c128vector-dot", SCM_OBJ(x), y, FALSE)) {
    case ARGTYPE_UVECTOR:
        for (int i=0; i<size; i++) {
            vx = SCM_C128VECTOR_ELEMENTS(x)[i];
            vy = SCM_C128VECTOR_ELEMENTS(y)[i];
            r = c128muladd(vx, vy, r, &rr);
        }
        break;
    case ARGTYPE_VECTOR:
        for (int i=0; i<size; i++) {
            vx = SCM_C128VECTOR_ELEMENTS(x)[i];
            vvy = SCM_VECTOR_ELEMENTS(y)[i];
            vy = c128num(vvy, &oor);
            if (!oor) {
                r = c128muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_DoubleComplexToComplex(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_LIST:
        for (int i=0; i<size; i++) {
            vx = SCM_C128VECTOR_ELEMENTS(x)[i];
            vvy = SCM_CAR(y); y = SCM_CDR(y);
            vy = c128num(vvy, &oor);
            if (!oor) {
                r = c128muladd(vx, vy, r, &rr);
            } else {
                vvx = Scm_DoubleComplexToComplex(vx);
                rr = Scm_Add(rr, Scm_Mul(vvx, vvy));
            }
        }
        break;
    case ARGTYPE_CONST:
        /* this case should've been eliminated by arg2_check. */
        Scm_Panic("something wrong");
    }

    /* r may contain a value bigger than the normal element value
       of c128vector, so it needs some care. */
    if (SCM_EQ(rr, SCM_MAKE_INT(0))) {
        if (vmp) {
            rr = Scm_DoubleComplexToComplex(r);
        } else {
            rr = Scm_DoubleComplexToComplex(r);
        }
    } else {
        ScmObj sr;
        sr = Scm_DoubleComplexToComplex(r);
        rr = Scm_Add(rr, sr);
    }
    return rr;
}

ScmObj Scm_C128VectorDotProd(ScmUVector *x, ScmObj y)
{
    return C128VectorDotProd(x, y, FALSE);
}

ScmObj Scm_VMC128VectorDotProd(ScmUVector *x, ScmObj y)
{
    return C128VectorDotProd(x, y, TRUE);
}

ScmObj Scm_S8VectorRangeCheck(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_S8VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("s8vector-range-check", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("s8vector-range-check", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetInteger8Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetInteger8Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_S8VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_S8VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_S8VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            return Scm_MakeInteger(i);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            return Scm_MakeInteger(i);
        }
    }
    return SCM_FALSE;
}

ScmObj Scm_S8VectorClamp(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_S8VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ScmObj d = Scm_UVectorCopy(SCM_UVECTOR(x), 0, -1);

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("s8vector-clamp", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("s8vector-clamp", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetInteger8Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetInteger8Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_S8VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_S8VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_S8VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_S8VECTOR_ELEMENTS(d)[i] = (int8_t)(val);
        }
    }
    return d;
}

ScmObj Scm_S8VectorClampX(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_S8VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("s8vector-clamp!", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("s8vector-clamp!", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetInteger8Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetInteger8Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_S8VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_S8VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_S8VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_S8VECTOR_ELEMENTS(x)[i] = (int8_t)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_S8VECTOR_ELEMENTS(x)[i] = (int8_t)(val);
        }
    }
    return SCM_OBJ(x);
}

ScmObj Scm_U8VectorRangeCheck(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_U8VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("u8vector-range-check", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("u8vector-range-check", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetIntegerU8Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetIntegerU8Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_U8VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_U8VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_U8VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            return Scm_MakeInteger(i);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            return Scm_MakeInteger(i);
        }
    }
    return SCM_FALSE;
}

ScmObj Scm_U8VectorClamp(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_U8VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ScmObj d = Scm_UVectorCopy(SCM_UVECTOR(x), 0, -1);

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("u8vector-clamp", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("u8vector-clamp", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetIntegerU8Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetIntegerU8Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_U8VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_U8VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_U8VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_U8VECTOR_ELEMENTS(d)[i] = (uint8_t)(val);
        }
    }
    return d;
}

ScmObj Scm_U8VectorClampX(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_U8VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("u8vector-clamp!", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("u8vector-clamp!", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetIntegerU8Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetIntegerU8Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_U8VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_U8VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_U8VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU8Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_U8VECTOR_ELEMENTS(x)[i] = (uint8_t)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_U8VECTOR_ELEMENTS(x)[i] = (uint8_t)(val);
        }
    }
    return SCM_OBJ(x);
}

ScmObj Scm_S16VectorRangeCheck(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_S16VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("s16vector-range-check", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("s16vector-range-check", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetInteger16Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetInteger16Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_S16VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_S16VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_S16VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            return Scm_MakeInteger(i);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            return Scm_MakeInteger(i);
        }
    }
    return SCM_FALSE;
}

ScmObj Scm_S16VectorClamp(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_S16VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ScmObj d = Scm_UVectorCopy(SCM_UVECTOR(x), 0, -1);

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("s16vector-clamp", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("s16vector-clamp", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetInteger16Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetInteger16Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_S16VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_S16VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_S16VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_S16VECTOR_ELEMENTS(d)[i] = (int16_t)(val);
        }
    }
    return d;
}

ScmObj Scm_S16VectorClampX(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_S16VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("s16vector-clamp!", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("s16vector-clamp!", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetInteger16Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetInteger16Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_S16VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_S16VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_S16VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_S16VECTOR_ELEMENTS(x)[i] = (int16_t)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_S16VECTOR_ELEMENTS(x)[i] = (int16_t)(val);
        }
    }
    return SCM_OBJ(x);
}

ScmObj Scm_U16VectorRangeCheck(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_U16VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("u16vector-range-check", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("u16vector-range-check", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetIntegerU16Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetIntegerU16Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_U16VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_U16VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_U16VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            return Scm_MakeInteger(i);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            return Scm_MakeInteger(i);
        }
    }
    return SCM_FALSE;
}

ScmObj Scm_U16VectorClamp(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_U16VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ScmObj d = Scm_UVectorCopy(SCM_UVECTOR(x), 0, -1);

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("u16vector-clamp", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("u16vector-clamp", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetIntegerU16Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetIntegerU16Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_U16VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_U16VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_U16VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_U16VECTOR_ELEMENTS(d)[i] = (uint16_t)(val);
        }
    }
    return d;
}

ScmObj Scm_U16VectorClampX(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_U16VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("u16vector-clamp!", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("u16vector-clamp!", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetIntegerU16Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetIntegerU16Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_U16VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_U16VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_U16VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU16Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_U16VECTOR_ELEMENTS(x)[i] = (uint16_t)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_U16VECTOR_ELEMENTS(x)[i] = (uint16_t)(val);
        }
    }
    return SCM_OBJ(x);
}

ScmObj Scm_S32VectorRangeCheck(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_S32VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("s32vector-range-check", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("s32vector-range-check", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetInteger32Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetInteger32Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_S32VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_S32VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_S32VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            return Scm_MakeInteger(i);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            return Scm_MakeInteger(i);
        }
    }
    return SCM_FALSE;
}

ScmObj Scm_S32VectorClamp(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_S32VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ScmObj d = Scm_UVectorCopy(SCM_UVECTOR(x), 0, -1);

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("s32vector-clamp", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("s32vector-clamp", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetInteger32Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetInteger32Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_S32VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_S32VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_S32VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_S32VECTOR_ELEMENTS(d)[i] = (int32_t)(val);
        }
    }
    return d;
}

ScmObj Scm_S32VectorClampX(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_S32VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("s32vector-clamp!", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("s32vector-clamp!", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetInteger32Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetInteger32Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (long)SCM_S32VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (long)SCM_S32VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (long)SCM_S32VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_S32VECTOR_ELEMENTS(x)[i] = (int32_t)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_S32VECTOR_ELEMENTS(x)[i] = (int32_t)(val);
        }
    }
    return SCM_OBJ(x);
}

ScmObj Scm_U32VectorRangeCheck(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_U32VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    u_long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("u32vector-range-check", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("u32vector-range-check", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetIntegerU32Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetIntegerU32Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (u_long)SCM_U32VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (u_long)SCM_U32VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (u_long)SCM_U32VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            return Scm_MakeInteger(i);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            return Scm_MakeInteger(i);
        }
    }
    return SCM_FALSE;
}

ScmObj Scm_U32VectorClamp(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_U32VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    u_long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ScmObj d = Scm_UVectorCopy(SCM_UVECTOR(x), 0, -1);

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("u32vector-clamp", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("u32vector-clamp", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetIntegerU32Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetIntegerU32Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (u_long)SCM_U32VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (u_long)SCM_U32VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (u_long)SCM_U32VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_U32VECTOR_ELEMENTS(d)[i] = (uint32_t)(val);
        }
    }
    return d;
}

ScmObj Scm_U32VectorClampX(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_U32VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    u_long val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("u32vector-clamp!", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("u32vector-clamp!", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetIntegerU32Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetIntegerU32Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = (u_long)SCM_U32VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (u_long)SCM_U32VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (u_long)SCM_U32VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU32Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_U32VECTOR_ELEMENTS(x)[i] = (uint32_t)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_U32VECTOR_ELEMENTS(x)[i] = (uint32_t)(val);
        }
    }
    return SCM_OBJ(x);
}

ScmObj Scm_S64VectorRangeCheck(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_S64VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    int64_t val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("s64vector-range-check", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("s64vector-range-check", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetInteger64Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetInteger64Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = SCM_S64VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = SCM_S64VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = SCM_S64VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && INT64LT(val, minval)) {
            val = minval;
            return Scm_MakeInteger(i);
        }
        if (!maxdc && INT64LT(maxval, val)) {
            val = maxval;
            return Scm_MakeInteger(i);
        }
    }
    return SCM_FALSE;
}

ScmObj Scm_S64VectorClamp(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_S64VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    int64_t val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ScmObj d = Scm_UVectorCopy(SCM_UVECTOR(x), 0, -1);

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("s64vector-clamp", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("s64vector-clamp", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetInteger64Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetInteger64Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = SCM_S64VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = SCM_S64VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = SCM_S64VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && INT64LT(val, minval)) {
            val = minval;
            SCM_S64VECTOR_ELEMENTS(d)[i] = val;
        }
        if (!maxdc && INT64LT(maxval, val)) {
            val = maxval;
            SCM_S64VECTOR_ELEMENTS(d)[i] = val;
        }
    }
    return d;
}

ScmObj Scm_S64VectorClampX(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_S64VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    int64_t val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("s64vector-clamp!", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("s64vector-clamp!", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetInteger64Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetInteger64Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = SCM_S64VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = SCM_S64VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetInteger64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = SCM_S64VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetInteger64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && INT64LT(val, minval)) {
            val = minval;
            SCM_S64VECTOR_ELEMENTS(x)[i] = val;
        }
        if (!maxdc && INT64LT(maxval, val)) {
            val = maxval;
            SCM_S64VECTOR_ELEMENTS(x)[i] = val;
        }
    }
    return SCM_OBJ(x);
}

ScmObj Scm_U64VectorRangeCheck(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_U64VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    uint64_t val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("u64vector-range-check", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("u64vector-range-check", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetIntegerU64Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetIntegerU64Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = SCM_U64VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = SCM_U64VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = SCM_U64VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && INT64LT(val, minval)) {
            val = minval;
            return Scm_MakeInteger(i);
        }
        if (!maxdc && INT64LT(maxval, val)) {
            val = maxval;
            return Scm_MakeInteger(i);
        }
    }
    return SCM_FALSE;
}

ScmObj Scm_U64VectorClamp(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_U64VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    uint64_t val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ScmObj d = Scm_UVectorCopy(SCM_UVECTOR(x), 0, -1);

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("u64vector-clamp", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("u64vector-clamp", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetIntegerU64Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetIntegerU64Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = SCM_U64VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = SCM_U64VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = SCM_U64VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && INT64LT(val, minval)) {
            val = minval;
            SCM_U64VECTOR_ELEMENTS(d)[i] = val;
        }
        if (!maxdc && INT64LT(maxval, val)) {
            val = maxval;
            SCM_U64VECTOR_ELEMENTS(d)[i] = val;
        }
    }
    return d;
}

ScmObj Scm_U64VectorClampX(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_U64VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    uint64_t val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("u64vector-clamp!", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("u64vector-clamp!", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetIntegerU64Clamp(min, SCM_CLAMP_BOTH, NULL);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetIntegerU64Clamp(max, SCM_CLAMP_BOTH, NULL);
};
    }

    for (int i=0; i<size; i++) {
        val = SCM_U64VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = SCM_U64VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = SCM_U64VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetIntegerU64Clamp(vv, SCM_CLAMP_BOTH, NULL);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && INT64LT(val, minval)) {
            val = minval;
            SCM_U64VECTOR_ELEMENTS(x)[i] = val;
        }
        if (!maxdc && INT64LT(maxval, val)) {
            val = maxval;
            SCM_U64VECTOR_ELEMENTS(x)[i] = val;
        }
    }
    return SCM_OBJ(x);
}

ScmObj Scm_F16VectorRangeCheck(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_F16VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    double val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("f16vector-range-check", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("f16vector-range-check", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetDouble(min);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetDouble(max);
};
    }

    for (int i=0; i<size; i++) {
        val = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(x)[i]);
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(min)[i]); break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(max)[i]); break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            return Scm_MakeInteger(i);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            return Scm_MakeInteger(i);
        }
    }
    return SCM_FALSE;
}

ScmObj Scm_F16VectorClamp(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_F16VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    double val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ScmObj d = Scm_UVectorCopy(SCM_UVECTOR(x), 0, -1);

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("f16vector-clamp", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("f16vector-clamp", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetDouble(min);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetDouble(max);
};
    }

    for (int i=0; i<size; i++) {
        val = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(x)[i]);
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(min)[i]); break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(max)[i]); break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_F16VECTOR_ELEMENTS(d)[i] = Scm_DoubleToHalf(val);
        }
    }
    return d;
}

ScmObj Scm_F16VectorClampX(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_F16VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    double val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("f16vector-clamp!", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("f16vector-clamp!", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetDouble(min);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetDouble(max);
};
    }

    for (int i=0; i<size; i++) {
        val = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(x)[i]);
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(min)[i]); break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = Scm_HalfToDouble(SCM_F16VECTOR_ELEMENTS(max)[i]); break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_F16VECTOR_ELEMENTS(x)[i] = Scm_DoubleToHalf(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_F16VECTOR_ELEMENTS(x)[i] = Scm_DoubleToHalf(val);
        }
    }
    return SCM_OBJ(x);
}

ScmObj Scm_F32VectorRangeCheck(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_F32VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    double val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("f32vector-range-check", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("f32vector-range-check", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetDouble(min);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetDouble(max);
};
    }

    for (int i=0; i<size; i++) {
        val = (double)SCM_F32VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (double)SCM_F32VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (double)SCM_F32VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            return Scm_MakeInteger(i);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            return Scm_MakeInteger(i);
        }
    }
    return SCM_FALSE;
}

ScmObj Scm_F32VectorClamp(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_F32VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    double val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ScmObj d = Scm_UVectorCopy(SCM_UVECTOR(x), 0, -1);

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("f32vector-clamp", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("f32vector-clamp", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetDouble(min);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetDouble(max);
};
    }

    for (int i=0; i<size; i++) {
        val = (double)SCM_F32VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (double)SCM_F32VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (double)SCM_F32VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_F32VECTOR_ELEMENTS(d)[i] = (float)(val);
        }
    }
    return d;
}

ScmObj Scm_F32VectorClampX(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_F32VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    double val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("f32vector-clamp!", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("f32vector-clamp!", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetDouble(min);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetDouble(max);
};
    }

    for (int i=0; i<size; i++) {
        val = (double)SCM_F32VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = (double)SCM_F32VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = (double)SCM_F32VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_F32VECTOR_ELEMENTS(x)[i] = (float)(val);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_F32VECTOR_ELEMENTS(x)[i] = (float)(val);
        }
    }
    return SCM_OBJ(x);
}

ScmObj Scm_F64VectorRangeCheck(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_F64VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    double val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("f64vector-range-check", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("f64vector-range-check", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetDouble(min);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetDouble(max);
};
    }

    for (int i=0; i<size; i++) {
        val = SCM_F64VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = SCM_F64VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = SCM_F64VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            return Scm_MakeInteger(i);
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            return Scm_MakeInteger(i);
        }
    }
    return SCM_FALSE;
}

ScmObj Scm_F64VectorClamp(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_F64VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    double val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ScmObj d = Scm_UVectorCopy(SCM_UVECTOR(x), 0, -1);

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("f64vector-clamp", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("f64vector-clamp", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetDouble(min);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetDouble(max);
};
    }

    for (int i=0; i<size; i++) {
        val = SCM_F64VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = SCM_F64VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = SCM_F64VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_F64VECTOR_ELEMENTS(d)[i] = val;
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_F64VECTOR_ELEMENTS(d)[i] = val;
        }
    }
    return d;
}

ScmObj Scm_F64VectorClampX(ScmUVector *x, ScmObj min, ScmObj max)
{
    int size = SCM_F64VECTOR_SIZE(x);
    ArgType mintype, maxtype;
    double val, minval, maxval;
    int mindc = FALSE, maxdc = FALSE;         /* true if "don't care" */
    ScmObj vv;
    ;

    minval = 0;             /* make compiler happy */
    maxval = 0;             /* dittox */

    /* size check */
    if (SCM_FALSEP(min)) mintype = ARGTYPE_CONST;
    else mintype = arg2_check("f64vector-clamp!", SCM_OBJ(x), min, TRUE);

    if (SCM_FALSEP(max)) maxtype = ARGTYPE_CONST;
    else maxtype = arg2_check("f64vector-clamp!", SCM_OBJ(x), max, TRUE);

    if (mintype == ARGTYPE_CONST) {
        if ((mindc = SCM_FALSEP(min)) == FALSE) {
  minval = Scm_GetDouble(min);
};
    }
    if (maxtype == ARGTYPE_CONST) {
        if ((maxdc = SCM_FALSEP(max)) == FALSE) {
  maxval = Scm_GetDouble(max);
};
    }

    for (int i=0; i<size; i++) {
        val = SCM_F64VECTOR_ELEMENTS(x)[i];
        switch (mintype) {
        case ARGTYPE_UVECTOR:
            minval = SCM_F64VECTOR_ELEMENTS(min)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(min)[i];
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(min); min = SCM_CDR(min);
            if ((mindc = SCM_FALSEP(vv)) == FALSE) {
  minval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }
        switch (maxtype) {
        case ARGTYPE_UVECTOR:
            maxval = SCM_F64VECTOR_ELEMENTS(max)[i]; break;
        case ARGTYPE_VECTOR:
            vv = SCM_VECTOR_ELEMENTS(max)[i];
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_LIST:
            vv = SCM_CAR(max); max = SCM_CDR(max);
            if ((maxdc = SCM_FALSEP(vv)) == FALSE) {
  maxval = Scm_GetDouble(vv);
};
            break;
        case ARGTYPE_CONST:
            /* alreadh handled above */
            break;
        }

        if (!mindc && (val < minval)) {
            val = minval;
            SCM_F64VECTOR_ELEMENTS(x)[i] = val;
        }
        if (!maxdc && (maxval < val)) {
            val = maxval;
            SCM_F64VECTOR_ELEMENTS(x)[i] = val;
        }
    }
    return SCM_OBJ(x);
}

static void s16vector_swapb(ScmUVector *v)
{
    int len = SCM_UVECTOR_SIZE(v);
    int16_t *d = SCM_S16VECTOR_ELEMENTS(v);
    for (int i=0; i<len; i++, d++) {
        swap_s16_t v;
        v.val = *d;
        SWAP_2(v);
        *d = v.val;
    }
}

ScmObj Scm_S16VectorSwapBytes(ScmUVector *v)
{
    ScmObj d = Scm_S16VectorCopy(v, 0, -1);
    s16vector_swapb(SCM_S16VECTOR(d));
    return d;
}

ScmObj Scm_S16VectorSwapBytesX(ScmUVector *v)
{
    SCM_UVECTOR_CHECK_MUTABLE(v);
    s16vector_swapb(v);
    return SCM_OBJ(v);
}


static void u16vector_swapb(ScmUVector *v)
{
    int len = SCM_UVECTOR_SIZE(v);
    uint16_t *d = SCM_U16VECTOR_ELEMENTS(v);
    for (int i=0; i<len; i++, d++) {
        swap_u16_t v;
        v.val = *d;
        SWAP_2(v);
        *d = v.val;
    }
}

ScmObj Scm_U16VectorSwapBytes(ScmUVector *v)
{
    ScmObj d = Scm_U16VectorCopy(v, 0, -1);
    u16vector_swapb(SCM_U16VECTOR(d));
    return d;
}

ScmObj Scm_U16VectorSwapBytesX(ScmUVector *v)
{
    SCM_UVECTOR_CHECK_MUTABLE(v);
    u16vector_swapb(v);
    return SCM_OBJ(v);
}


static void s32vector_swapb(ScmUVector *v)
{
    int len = SCM_UVECTOR_SIZE(v);
    int32_t *d = SCM_S32VECTOR_ELEMENTS(v);
    for (int i=0; i<len; i++, d++) {
        swap_s32_t v;
        v.val = *d;
        SWAP_4(v);
        *d = v.val;
    }
}

ScmObj Scm_S32VectorSwapBytes(ScmUVector *v)
{
    ScmObj d = Scm_S32VectorCopy(v, 0, -1);
    s32vector_swapb(SCM_S32VECTOR(d));
    return d;
}

ScmObj Scm_S32VectorSwapBytesX(ScmUVector *v)
{
    SCM_UVECTOR_CHECK_MUTABLE(v);
    s32vector_swapb(v);
    return SCM_OBJ(v);
}


static void u32vector_swapb(ScmUVector *v)
{
    int len = SCM_UVECTOR_SIZE(v);
    uint32_t *d = SCM_U32VECTOR_ELEMENTS(v);
    for (int i=0; i<len; i++, d++) {
        swap_u32_t v;
        v.val = *d;
        SWAP_4(v);
        *d = v.val;
    }
}

ScmObj Scm_U32VectorSwapBytes(ScmUVector *v)
{
    ScmObj d = Scm_U32VectorCopy(v, 0, -1);
    u32vector_swapb(SCM_U32VECTOR(d));
    return d;
}

ScmObj Scm_U32VectorSwapBytesX(ScmUVector *v)
{
    SCM_UVECTOR_CHECK_MUTABLE(v);
    u32vector_swapb(v);
    return SCM_OBJ(v);
}


static void s64vector_swapb(ScmUVector *v)
{
    int len = SCM_UVECTOR_SIZE(v);
    int64_t *d = SCM_S64VECTOR_ELEMENTS(v);
    for (int i=0; i<len; i++, d++) {
        swap_s64_t v;
        v.val = *d;
        SWAP_8(v);
        *d = v.val;
    }
}

ScmObj Scm_S64VectorSwapBytes(ScmUVector *v)
{
    ScmObj d = Scm_S64VectorCopy(v, 0, -1);
    s64vector_swapb(SCM_S64VECTOR(d));
    return d;
}

ScmObj Scm_S64VectorSwapBytesX(ScmUVector *v)
{
    SCM_UVECTOR_CHECK_MUTABLE(v);
    s64vector_swapb(v);
    return SCM_OBJ(v);
}


static void u64vector_swapb(ScmUVector *v)
{
    int len = SCM_UVECTOR_SIZE(v);
    uint64_t *d = SCM_U64VECTOR_ELEMENTS(v);
    for (int i=0; i<len; i++, d++) {
        swap_u64_t v;
        v.val = *d;
        SWAP_8(v);
        *d = v.val;
    }
}

ScmObj Scm_U64VectorSwapBytes(ScmUVector *v)
{
    ScmObj d = Scm_U64VectorCopy(v, 0, -1);
    u64vector_swapb(SCM_U64VECTOR(d));
    return d;
}

ScmObj Scm_U64VectorSwapBytesX(ScmUVector *v)
{
    SCM_UVECTOR_CHECK_MUTABLE(v);
    u64vector_swapb(v);
    return SCM_OBJ(v);
}


static void f16vector_swapb(ScmUVector *v)
{
    int len = SCM_UVECTOR_SIZE(v);
    ScmHalfFloat *d = SCM_F16VECTOR_ELEMENTS(v);
    for (int i=0; i<len; i++, d++) {
        swap_f16_t v;
        v.val = *d;
        SWAP_2(v);
        *d = v.val;
    }
}

ScmObj Scm_F16VectorSwapBytes(ScmUVector *v)
{
    ScmObj d = Scm_F16VectorCopy(v, 0, -1);
    f16vector_swapb(SCM_F16VECTOR(d));
    return d;
}

ScmObj Scm_F16VectorSwapBytesX(ScmUVector *v)
{
    SCM_UVECTOR_CHECK_MUTABLE(v);
    f16vector_swapb(v);
    return SCM_OBJ(v);
}


static void f32vector_swapb(ScmUVector *v)
{
    int len = SCM_UVECTOR_SIZE(v);
    float *d = SCM_F32VECTOR_ELEMENTS(v);
    for (int i=0; i<len; i++, d++) {
        swap_f32_t v;
        v.val = *d;
        SWAP_4(v);
        *d = v.val;
    }
}

ScmObj Scm_F32VectorSwapBytes(ScmUVector *v)
{
    ScmObj d = Scm_F32VectorCopy(v, 0, -1);
    f32vector_swapb(SCM_F32VECTOR(d));
    return d;
}

ScmObj Scm_F32VectorSwapBytesX(ScmUVector *v)
{
    SCM_UVECTOR_CHECK_MUTABLE(v);
    f32vector_swapb(v);
    return SCM_OBJ(v);
}


static void f64vector_swapb(ScmUVector *v)
{
    int len = SCM_UVECTOR_SIZE(v);
    double *d = SCM_F64VECTOR_ELEMENTS(v);
    for (int i=0; i<len; i++, d++) {
        swap_f64_t v;
        v.val = *d;
        SWAP_8(v);
        *d = v.val;
    }
}

ScmObj Scm_F64VectorSwapBytes(ScmUVector *v)
{
    ScmObj d = Scm_F64VectorCopy(v, 0, -1);
    f64vector_swapb(SCM_F64VECTOR(d));
    return d;
}

ScmObj Scm_F64VectorSwapBytesX(ScmUVector *v)
{
    SCM_UVECTOR_CHECK_MUTABLE(v);
    f64vector_swapb(v);
    return SCM_OBJ(v);
}


/*==============================================================
 * Some generic functions
 */

/*
 * Generic copy
 */
ScmObj Scm_UVectorCopy(ScmUVector *v, ScmSmallInt start, ScmSmallInt end)
{
    switch (Scm_UVectorType(Scm_ClassOf(SCM_OBJ(v)))) {
    case SCM_UVECTOR_S8: return Scm_S8VectorCopy(v, start, end);
    case SCM_UVECTOR_U8: return Scm_U8VectorCopy(v, start, end);
    case SCM_UVECTOR_S16: return Scm_S16VectorCopy(v, start, end);
    case SCM_UVECTOR_U16: return Scm_U16VectorCopy(v, start, end);
    case SCM_UVECTOR_S32: return Scm_S32VectorCopy(v, start, end);
    case SCM_UVECTOR_U32: return Scm_U32VectorCopy(v, start, end);
    case SCM_UVECTOR_S64: return Scm_S64VectorCopy(v, start, end);
    case SCM_UVECTOR_U64: return Scm_U64VectorCopy(v, start, end);
    case SCM_UVECTOR_F16: return Scm_F16VectorCopy(v, start, end);
    case SCM_UVECTOR_F32: return Scm_F32VectorCopy(v, start, end);
    case SCM_UVECTOR_F64: return Scm_F64VectorCopy(v, start, end);
    case SCM_UVECTOR_C32: return Scm_C32VectorCopy(v, start, end);
    case SCM_UVECTOR_C64: return Scm_C64VectorCopy(v, start, end);
    case SCM_UVECTOR_C128: return Scm_C128VectorCopy(v, start, end);
    default: Scm_Error("uniform vector required, but got %S", v);
        return SCM_UNDEFINED;
    }
}

/*
 * Generic swapb
 */
ScmObj Scm_UVectorSwapBytes(ScmUVector *v, int option)
{
    switch (Scm_UVectorType(Scm_ClassOf(SCM_OBJ(v)))) {
    case SCM_UVECTOR_S8:  return SCM_OBJ(v);
    case SCM_UVECTOR_U8:  return SCM_OBJ(v);
    case SCM_UVECTOR_S16: return Scm_S16VectorSwapBytes(v);
    case SCM_UVECTOR_U16: return Scm_U16VectorSwapBytes(v);
    case SCM_UVECTOR_S32: return Scm_S32VectorSwapBytes(v);
    case SCM_UVECTOR_U32: return Scm_U32VectorSwapBytes(v);
    case SCM_UVECTOR_S64: return Scm_S64VectorSwapBytes(v);
    case SCM_UVECTOR_U64: return Scm_U64VectorSwapBytes(v);
    case SCM_UVECTOR_F16: return Scm_F16VectorSwapBytes(v);
    case SCM_UVECTOR_F32: return Scm_F32VectorSwapBytes(v);
    case SCM_UVECTOR_F64:
        switch (option) {
        case SWAPB_ARM_LE: return Scm_F64VectorSwapBytes_ARM2LE(v);
        case SWAPB_ARM_BE: return Scm_F64VectorSwapBytes_ARM2BE(v);
        default:           return Scm_F64VectorSwapBytes(v);
        }
    default: Scm_Error("uniform vector required, but got %S", v);
        return SCM_UNDEFINED;
    }
}

ScmObj Scm_UVectorSwapBytesX(ScmUVector *v, int option)
{
    switch (Scm_UVectorType(Scm_ClassOf(SCM_OBJ(v)))) {
    case SCM_UVECTOR_S8:  return SCM_OBJ(v);
    case SCM_UVECTOR_U8:  return SCM_OBJ(v);
    case SCM_UVECTOR_S16: return Scm_S16VectorSwapBytesX(v);
    case SCM_UVECTOR_U16: return Scm_U16VectorSwapBytesX(v);
    case SCM_UVECTOR_S32: return Scm_S32VectorSwapBytesX(v);
    case SCM_UVECTOR_U32: return Scm_U32VectorSwapBytesX(v);
    case SCM_UVECTOR_S64: return Scm_S64VectorSwapBytesX(v);
    case SCM_UVECTOR_U64: return Scm_U64VectorSwapBytesX(v);
    case SCM_UVECTOR_F16: return Scm_F16VectorSwapBytesX(v);
    case SCM_UVECTOR_F32: return Scm_F32VectorSwapBytesX(v);
    case SCM_UVECTOR_F64:
        switch (option) {
        case SWAPB_ARM_LE: return Scm_F64VectorSwapBytesX_ARM2LE(v);
        case SWAPB_ARM_BE: return Scm_F64VectorSwapBytesX_ARM2BE(v);
        default:           return Scm_F64VectorSwapBytesX(v);
        }
    default: Scm_Error("uniform vector required, but got %S", v);
        return SCM_UNDEFINED;
    }
}

/*
 * Block I/O
 */

ScmObj Scm_ReadBlockX(ScmUVector *v, ScmPort *port,
                      ScmSmallInt start, ScmSmallInt end, ScmSymbol *endian)
{
    ScmSmallInt len = SCM_UVECTOR_SIZE(v);

    SCM_CHECK_START_END(start, end, len);
    SCM_UVECTOR_CHECK_MUTABLE(v);
    SCM_CHECK_ENDIAN(endian);

    int eltsize = Scm_UVectorElementSize(Scm_ClassOf(SCM_OBJ(v)));
    SCM_ASSERT(eltsize >= 1);
    ScmSize r = Scm_Getz((char*)v->elements + start*eltsize,
                         (end-start)*eltsize, port);
    if (r == EOF) SCM_RETURN(SCM_EOF);
#ifdef DOUBLE_ARMENDIAN
    if (SCM_EQ(Scm_NativeEndian(), SCM_SYM_ARM_LITTLE_ENDIAN)) {
        if (SCM_EQ(SCM_OBJ(endian), SCM_SYM_LITTLE_ENDIAN)) {
            /* arm-le and le is equivalent when eltsize <= 4 */
            if (eltsize == 8) {
                Scm_UVectorSwapBytesX(SCM_UVECTOR(v), SWAPB_ARM_LE);
            }
        } else if (SCM_EQ(SCM_OBJ(endian), SCM_SYM_BIG_ENDIAN)) {
            Scm_UVectorSwapBytesX(SCM_UVECTOR(v), SWAPB_ARM_BE);
        }
    } else
#endif /*!DOUBLE_ARMENDIAN*/
        {
#ifdef WORDS_BIGENDIAN
            if (SCM_EQ(SCM_OBJ(endian), SCM_SYM_LITTLE_ENDIAN)) {
                Scm_UVectorSwapBytesX(SCM_UVECTOR(v), SWAPB_STD);
            } else if (SCM_EQ(SCM_OBJ(endian), SCM_SYM_ARM_LITTLE_ENDIAN)) {
                Scm_UVectorSwapBytesX(SCM_UVECTOR(v), SWAPB_ARM_BE);
            }
#else  /*!WORDS_BIGENDIAN*/
            if (SCM_EQ(SCM_OBJ(endian), SCM_SYM_BIG_ENDIAN)) {
                Scm_UVectorSwapBytesX(SCM_UVECTOR(v), SWAPB_STD);
            } else if (SCM_EQ(SCM_OBJ(endian), SCM_SYM_ARM_LITTLE_ENDIAN)) {
                if (eltsize == 8) {
                    Scm_UVectorSwapBytesX(SCM_UVECTOR(v), SWAPB_ARM_LE);
                }
            }
#endif /*!WORDS_BIGENDIAN*/
        }
    SCM_RETURN(Scm_MakeInteger(r/eltsize));
}

ScmObj Scm_WriteBlock(ScmUVector *v, ScmPort *port,
                      ScmSmallInt start, ScmSmallInt end, ScmSymbol *endian)
{
    ScmSmallInt len = SCM_UVECTOR_SIZE(v);
    int swap_needed = FALSE, swap_type;
    SCM_CHECK_START_END(start, end, len);
    SCM_CHECK_ENDIAN(endian);

    int eltsize = Scm_UVectorElementSize(Scm_ClassOf(SCM_OBJ(v)));
    SCM_ASSERT(eltsize >= 1);
#ifdef DOUBLE_ARMENDIAN
    if (SCM_EQ(Scm_NativeEndian(), SCM_SYM_ARM_LITTLE_ENDIAN)) {
        if (SCM_EQ(SCM_OBJ(endian), SCM_SYM_BIG_ENDIAN)) {
            swap_needed = TRUE;
            swap_type = SWAPB_ARM_BE;
        } else if (SCM_EQ(SCM_OBJ(endian), SCM_SYM_LITTLE_ENDIAN)
                   && eltsize == 8) {
            swap_needed = TRUE;
            swap_type = SWAPB_ARM_LE;
        }
    } else
#endif /*DOUBLE_ARMENDIAN*/
        {
#ifdef WORDS_BIGENDIAN
            if (SCM_EQ(SCM_OBJ(endian), SCM_SYM_LITTLE_ENDIAN)) {
                swap_needed = TRUE;
                swap_type = SWAPB_STD;
            } else if (SCM_EQ(SCM_OBJ(endian), SCM_SYM_ARM_LITTLE_ENDIAN)) {
                swap_needed = TRUE;
                swap_type = SWAPB_ARM_BE;
            }
#else /*!WORDS_BIGENDIAN*/
            if (SCM_EQ(SCM_OBJ(endian), SCM_SYM_BIG_ENDIAN)) {
                swap_needed = TRUE;
                swap_type = SWAPB_STD;
            } else if (SCM_EQ(SCM_OBJ(endian), SCM_SYM_ARM_LITTLE_ENDIAN)
                       && eltsize == 8) {
                swap_needed = TRUE;
                swap_type = SWAPB_ARM_LE;
            }
#endif  /*!WORDS_BIGENDIAN*/
        }
    if (!swap_needed || eltsize == 1) {
        Scm_Putz((const char*)v->elements + start*eltsize,
                 (end-start)*eltsize, port);
    } else {
        /* ugly */
        switch (eltsize) {
        case 2: {
            swap_u16_t d;
            for (ScmSmallInt i=start; i<end; i++) {
                d.val = ((uint16_t*)v->elements)[i];
                SWAP_2(d);
                Scm_Putz((const char*)d.buf, 2, port);
            }
            break;
        }
        case 4: {
            swap_u32_t d;
            for (ScmSmallInt i=start; i<end; i++) {
                d.val = ((uint32_t*)v->elements)[i];
                SWAP_4(d);
                Scm_Putz((const char*)d.buf, 4, port);
            }
            break;
        }
        case 8:{
            swap_u64_t d;
            switch (swap_type) {
            case SWAPB_STD:
                for (ScmSmallInt i=start; i<end; i++) {
                    d.val = ((uint64_t*)v->elements)[i];
                    SWAP_8(d);
                    Scm_Putz((const char*)d.buf, 8, port);
                }
                break;
            case SWAPB_ARM_LE:
                for (ScmSmallInt i=start; i<end; i++) {
                    d.val = ((uint64_t*)v->elements)[i];
                    SWAP_ARM2LE(d);
                    Scm_Putz((const char*)d.buf, 8, port);
                }
                break;
            case SWAPB_ARM_BE:
                for (ScmSmallInt i=start; i<end; i++) {
                    d.val = ((uint64_t*)v->elements)[i];
                    SWAP_ARM2BE(d);
                    Scm_Putz((const char*)d.buf, 8, port);
                }
                break;
            }
            break;
        }
        }
    }
    SCM_RETURN(SCM_UNDEFINED);
}

